JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS></code>.
*/
public static JavaType unknownType() {
return defaultInstance()._unknownType();
}
/**
* Static helper method that can be called to figure out type-erased
* call for given JDK type. It can be called statically since type resolution
* process can never change actual type-erased class; thereby static
* default instance is used for determination.
*/
public static Class<?> rawClass(Type t) {
if (t instanceof Class<?>) {
return (Class<?>) t;
}
// Shouldbe able to optimize bit more in future...
return defaultInstance().constructType(t).getRawClass();
}
/*
/**********************************************************
/* Type conversion, parameterization resolution methods
/**********************************************************
*/
/**
* Factory method for creating a subtype of given base type, as defined
* by specified subclass; but retaining generic type information if any.
* Can be used, for example, to get equivalent of "HashMap<String,Integer>"
* from "Map<String,Integer>" by giving <code>HashMap.class</code>
* as subclass.
*/
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass)
{
// simple optimization to avoid costly introspection if type-erased type does NOT differ
if (baseType.getRawClass() == subclass) {
return baseType;
}
// Currently only SimpleType instances can become something else
if (baseType instanceof SimpleType) {
// and only if subclass is an array, Collection or Map
if (subclass.isArray()
|| Map.class.isAssignableFrom(subclass)
|| Collection.class.isAssignableFrom(subclass)) {
// need to assert type compatibility...
if (!baseType.getRawClass().isAssignableFrom(subclass)) {
throw new IllegalArgumentException("Class "+subclass.getClass().getName()+" not subtype of "+baseType);
}
// this _should_ work, right?
JavaType subtype = _fromClass(subclass, new TypeBindings(this, baseType.getRawClass()));
// one more thing: handlers to copy?
Object h = baseType.getValueHandler();
if (h != null) {
subtype = subtype.withValueHandler(h);
}
h = baseType.getTypeHandler();
if (h != null) {
subtype = subtype.withTypeHandler(h);
}
return subtype;
}
}
// otherwise regular narrowing should work just fine
return baseType.narrowBy(subclass);
}
/**
* Factory method for constructing a {@link JavaType} out of its canonical
* representation (see {@link JavaType#toCanonical()}).
*
* @param canonical Canonical string representation of a type
*
* @throws
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> IllegalArgumentException If canonical representation is malformed,
* or class that type represents (including its generic parameters) is
* not found
*/
public JavaType constructFromCanonical(String canonical) throws IllegalArgumentException
{
return _parser.parse(canonical);
}
/**
* Method that is to figure out actual type parameters that given
* class binds to generic types defined by given (generic)
* interface or class.
* This could mean, for example, trying to figure out
* key and value types for Map implementations.
*
* @param type Sub-type (leaf type) that implements <code>expType</code>
*/
public JavaType[] findTypeParameters(JavaType type, Class<?> expType)
{
/* Tricky part here is that some JavaType instances have been constructed
* from generic type (usually via TypeReference); and in those case
* types have been resolved. Alternative is that the leaf type is type-erased
* class, in which case this has not been done.
* For now simplest way to handle this is to split processing in two: latter
* case actually fully works; and former mostly works. In future may need to
* rewrite former part, which requires changes to JavaType as well.
*/
if (expType == type.getParameterSource()) {
// Direct type info; good since we can return it as is
int count = type.containedTypeCount();
if (count == 0) return null;
JavaType[] result = new JavaType[count];
for (int i = 0; i < count; ++i) {
result[i] = type.containedType(i);
}
return result;
}
/* Otherwise need to go through type-erased class. This may miss cases where
* we get generic type; ideally JavaType/SimpleType would retain information
* about generic declaration at main level... but let's worry about that
* if/when there are problems; current handling is an improvement over earlier
* code.
*/
Class<?> raw = type.getRawClass();
return findTypeParameters(raw, expType, new TypeBindings(this, type));
}
public JavaType[] findTypeParameters(Class<?> clz, Class<?> expType) {
return findTypeParameters(clz, expType, new TypeBindings(this, clz));
}
public JavaType[] findTypeParameters(Class<?> clz, Class<?> expType, TypeBindings bindings)
{
// First: find full inheritance chain
HierarchicType subType = _findSuperTypeChain(clz, expType);
// Caller is supposed to ensure this never happens, so:
if (subType == null) {
throw new IllegalArgumentException("Class "+clz.
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>getName()+" is not a subtype of "+expType.getName());
}
// Ok and then go to the ultimate super-type:
HierarchicType superType = subType;
while (superType.getSuperType() != null) {
superType = superType.getSuperType();
Class<?> raw = superType.getRawClass();
TypeBindings newBindings = new TypeBindings(this, raw);
if (superType.isGeneric()) { // got bindings, need to resolve
ParameterizedType pt = superType.asGeneric();
Type[] actualTypes = pt.getActualTypeArguments();
TypeVariable<?>[] vars = raw.getTypeParameters();
int len = actualTypes.length;
for (int i = 0; i < len; ++i) {
String name = vars[i].getName();
JavaType type = _constructType(actualTypes[i], bindings);
newBindings.addBinding(name, type);
}
}
bindings = newBindings;
}
// which ought to be generic (if not, it's raw type)
if (!superType.isGeneric()) {
return null;
}
return bindings.typesAsArray();
}
/**
* Method that can be called to figure out more specific of two
* types (if they are related; that is, one implements or extends the
* other); or if not related, return the primary type.
*
* @param type1 Primary type to consider
* @param type2 Secondary type to consider
*
* @since 2.2
*/
public JavaType moreSpecificType(JavaType type1, JavaType type2)
{
if (type1 == null) {
return type2;
}
if (type2 == null) {
return type1;
}
Class<?> raw1 = type1.getRawClass();
Class<?> raw2 = type2.getRawClass();
if (raw1 == raw2) {
return type1;
}
// TODO: maybe try sub-classing, to retain generic types?
if (raw1.isAssignableFrom(raw2)) {
return type2;
}
return type1;
}
/*
/**********************************************************
/* Public factory methods
/**********************************************************
*/
public JavaType constructType(Type type) {
return _constructType(type, null);
}
public JavaType constructType(Type type, TypeBindings bindings) {
return _constructType(type, bindings);
}
public JavaType constructType(TypeReference<?> typeRef) {
return _constructType(typeRef.getType(), null);
}
public JavaType constructType(Type type, Class<?> context) {
TypeBindings b = (context == null) ? null
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> : new TypeBindings(this, context);
return _constructType(type, b);
}
public JavaType constructType(Type type, JavaType context) {
TypeBindings b = (context == null) ? null : new TypeBindings(this, context);
return _constructType(type, b);
}
/**
* Factory method that can be used if type information is passed
* as Java typing returned from <code>getGenericXxx</code> methods
* (usually for a return or argument type).
*/
protected JavaType _constructType(Type type, TypeBindings context)
{
JavaType resultType;
// simple class?
if (type instanceof Class<?>) {
resultType = _fromClass((Class<?>) type, context);
}
// But if not, need to start resolving.
else if (type instanceof ParameterizedType) {
resultType = _fromParamType((ParameterizedType) type, context);
}
else if (type instanceof JavaType) { // [Issue#116]
return (JavaType) type;
}
else if (type instanceof GenericArrayType) {
resultType = _fromArrayType((GenericArrayType) type, context);
}
else if (type instanceof TypeVariable<?>) {
resultType = _fromVariable((TypeVariable<?>) type, context);
}
else if (type instanceof WildcardType) {
resultType = _fromWildcard((WildcardType) type, context);
} else {
// sanity check
throw new IllegalArgumentException("Unrecognized Type: "+((type == null) ? "[null]" : type.toString()));
}
/* [JACKSON-521]: Need to allow TypeModifiers to alter actual type; however,
* for now only call for simple types (i.e. not for arrays, map or collections).
* Can be changed in future it necessary
*/
if (_modifiers != null && !resultType.isContainerType()) {
for (TypeModifier mod : _modifiers) {
resultType = mod.modifyType(resultType, type, context, this);
}
}
return resultType;
}
/*
/**********************************************************
/* Direct factory methods
/**********************************************************
*/
/**
* Method for constructing an {@link ArrayType}.
*<p>
* NOTE: type modifiers are NOT called on array type itself; but are called
* for element type (and other contained types)
*/
public ArrayType constructArrayType(Class<?> elementType) {
return ArrayType.construct(_constructType(elementType, null), null, null);
}
/**
* Method for constructing an {@link ArrayType}.
*<p>
* NOTE: type modifiers are NOT called on array type itself; but are called
* for contained
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> types.
*/
public ArrayType constructArrayType(JavaType elementType) {
return ArrayType.construct(elementType, null, null);
}
/**
* Method for constructing a {@link CollectionType}.
*<p>
* NOTE: type modifiers are NOT called on Collection type itself; but are called
* for contained types.
*/
public CollectionType constructCollectionType(Class<? extends Collection> collectionClass, Class<?> elementClass) {
return CollectionType.construct(collectionClass, constructType(elementClass));
}
/**
* Method for constructing a {@link CollectionType}.
*<p>
* NOTE: type modifiers are NOT called on Collection type itself; but are called
* for contained types.
*/
public CollectionType constructCollectionType(Class<? extends Collection> collectionClass, JavaType elementType) {
return CollectionType.construct(collectionClass, elementType);
}
/**
* Method for constructing a {@link CollectionLikeType}.
*<p>
* NOTE: type modifiers are NOT called on constructed type itself; but are called
* for contained types.
*/
public CollectionLikeType constructCollectionLikeType(Class<?> collectionClass, Class<?> elementClass) {
return CollectionLikeType.construct(collectionClass, constructType(elementClass));
}
/**
* Method for constructing a {@link CollectionLikeType}.
*<p>
* NOTE: type modifiers are NOT called on constructed type itself; but are called
* for contained types.
*/
public CollectionLikeType constructCollectionLikeType(Class<?> collectionClass, JavaType elementType) {
return CollectionLikeType.construct(collectionClass, elementType);
}
/**
* Method for constructing a {@link MapType} instance
*<p>
* NOTE: type modifiers are NOT called on constructed type itself; but are called
* for contained types.
*/
public MapType constructMapType(Class<? extends Map> mapClass, JavaType keyType, JavaType valueType) {
return MapType.construct(mapClass, keyType, valueType);
}
/**
* Method for constructing a {@link MapType} instance
*<p>
* NOTE: type modifiers are NOT called on constructed type itself; but are called
* for contained types.
*/
public MapType constructMapType(Class<? extends Map> mapClass, Class<?> keyClass, Class<?> valueClass) {
return MapType.construct(mapClass, constructType(keyClass), constructType(valueClass));
}
/**
* Method for constructing a {@link MapLikeType} instance
*<p>
* NOTE: type modifiers are NOT called on constructed type itself; but are called
* for contained types.
*/
public MapLikeType constructMapLikeType(Class<?>
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> mapClass, JavaType keyType, JavaType valueType) {
return MapLikeType.construct(mapClass, keyType, valueType);
}
/**
* Method for constructing a {@link MapLikeType} instance
*<p>
* NOTE: type modifiers are NOT called on constructed type itself; but are called
* for contained types.
*/
public MapLikeType constructMapLikeType(Class<?> mapClass, Class<?> keyClass, Class<?> valueClass) {
return MapType.construct(mapClass, constructType(keyClass), constructType(valueClass));
}
/**
* Method for constructing a type instance with specified parameterization.
*
* @deprecated Since 2.5, use variant that takes one more argument
*/
@Deprecated
public JavaType constructSimpleType(Class<?> rawType, JavaType[] parameterTypes) {
return constructSimpleType(rawType, rawType, parameterTypes);
}
public JavaType constructSimpleType(Class<?> rawType, Class<?> parameterTarget,
JavaType[] parameterTypes)
{
// Quick sanity check: must match numbers of types with expected...
TypeVariable<?>[] typeVars = parameterTarget.getTypeParameters();
if (typeVars.length != parameterTypes.length) {
throw new IllegalArgumentException("Parameter type mismatch for "+rawType.getName()
+" (and target "+parameterTarget.getName()+"): expected "+typeVars.length
+" parameters, was given "+parameterTypes.length);
}
String[] names = new String[typeVars.length];
for (int i = 0, len = typeVars.length; i < len; ++i) {
names[i] = typeVars[i].getName();
}
return new SimpleType(rawType, names, parameterTypes, null, null, false, parameterTarget);
}
/**
* Method that will force construction of a simple type, without trying to
* check for more specialized types.
*<p>
* NOTE: no type modifiers are called on type either, so calling this method
* should only be used if caller really knows what it's doing...
*/
public JavaType uncheckedSimpleType(Class<?> cls) {
return new SimpleType(cls);
}
/**
* Factory method for constructing {@link JavaType} that
* represents a parameterized type. For example, to represent
* type <code>List<Set<Integer>></code>, you could
* call
*<pre>
* TypeFactory.parametricType(List.class, Integer.class);
*</pre>
*<p>
* NOTE: type modifiers are NOT called on constructed type itself; but are called
* for contained types.
*
* @param parametrized Type-
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>erased type of instance being constructed
* @param parametersFor class or interface for which type parameters are applied; either
* <code>parametrized</code> or one of its supertypes
* @param parameterClasses Type parameters to apply
*
* @since 2.5
*/
public JavaType constructParametrizedType(Class<?> parametrized, Class<?> parametersFor,
Class<?>... parameterClasses)
{
int len = parameterClasses.length;
JavaType[] pt = new JavaType[len];
for (int i = 0; i < len; ++i) {
pt[i] = _fromClass(parameterClasses[i], null);
}
return constructParametrizedType(parametrized, parametersFor, pt);
}
/**
* @deprecated Since 2.5, use {@link #constructParametrizedType} instead.
*/
@Deprecated
public JavaType constructParametricType(Class<?> parametrized, Class<?>... parameterClasses) {
return constructParametrizedType(parametrized, parametrized, parameterClasses);
}
/**
* Factory method for constructing {@link JavaType} that
* represents a parameterized type. For example, to represent
* type <code>List<Set<Integer>></code>, you could
* call
*<pre>
* JavaType inner = TypeFactory.parametricType(Set.class, Integer.class);
* TypeFactory.parametricType(List.class, inner);
*</pre>
*<p>
* NOTE: type modifiers are NOT called on constructed type itself; but are called
* for contained types.
*
*
* @param parametrized Actual full type
* @param parametersFor class or interface for which type parameters are applied; either
* <code>parametrized</code> or one of its supertypes
* @param parameterTypes Type parameters to apply
*
* @since 2.5
*/
public JavaType constructParametrizedType(Class<?> parametrized, Class<?> parametersFor,
JavaType... parameterTypes)
{
JavaType resultType;
// Need to check kind of class we are dealing with...
if (parametrized.isArray()) {
// 19-Jan-2010, tatus: should we support multi-dimensional arrays directly?
if (parameterTypes.length != 1) {
throw new IllegalArgumentException("Need exactly 1 parameter type for arrays ("+parametrized.getName()+")");
}
resultType = constructArrayType(parameterTypes[0]);
}
else if (Map.class.isAssignableFrom(parametrized)) {
if (parameterTypes.length != 2) {
throw new IllegalArgumentException("
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Need exactly 2 parameter types for Map types ("+parametrized.getName()+")");
}
resultType = constructMapType((Class<Map<?,?>>)parametrized, parameterTypes[0], parameterTypes[1]);
}
else if (Collection.class.isAssignableFrom(parametrized)) {
if (parameterTypes.length != 1) {
throw new IllegalArgumentException("Need exactly 1 parameter type for Collection types ("+parametrized.getName()+")");
}
resultType = constructCollectionType((Class<Collection<?>>)parametrized, parameterTypes[0]);
} else {
resultType = constructSimpleType(parametrized, parametersFor, parameterTypes);
}
return resultType;
}
/**
* @deprecated Since 2.5, use {@link #constructParametrizedType} instead.
*/
@Deprecated
public JavaType constructParametricType(Class<?> parametrized, JavaType... parameterTypes) {
return constructParametrizedType(parametrized, parametrized, parameterTypes);
}
/*
/**********************************************************
/* Direct factory methods for "raw" variants, used when
/* parameterization is unknown
/**********************************************************
*/
/**
* Method that can be used to construct "raw" Collection type; meaning that its
* parameterization is unknown.
* This is similar to using <code>Object.class</code> parameterization,
* and is equivalent to calling:
*<pre>
* typeFactory.constructCollectionType(collectionClass, typeFactory.unknownType());
*<pre>
*<p>
* This method should only be used if parameterization is completely unavailable.
*/
public CollectionType constructRawCollectionType(Class<? extends Collection> collectionClass) {
return CollectionType.construct(collectionClass, unknownType());
}
/**
* Method that can be used to construct "raw" Collection-like type; meaning that its
* parameterization is unknown.
* This is similar to using <code>Object.class</code> parameterization,
* and is equivalent to calling:
*<pre>
* typeFactory.constructCollectionLikeType(collectionClass, typeFactory.unknownType());
*<pre>
*<p>
* This method should only be used if parameterization is completely unavailable.
*/
public CollectionLikeType constructRawCollectionLikeType(Class<?> collectionClass) {
return CollectionLikeType.construct(collectionClass, unknownType());
}
/**
* Method that can be used to construct "raw" Map type; meaning that its
* parameterization is unknown.
* This is similar to using <code>Object.class</code> parameterization,
* and is equivalent to calling:
*<pre>
* typeFactory.constructMapType(
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>collectionClass, typeFactory.unknownType(), typeFactory.unknownType());
*<pre>
*<p>
* This method should only be used if parameterization is completely unavailable.
*/
public MapType constructRawMapType(Class<? extends Map> mapClass) {
return MapType.construct(mapClass, unknownType(), unknownType());
}
/**
* Method that can be used to construct "raw" Map-like type; meaning that its
* parameterization is unknown.
* This is similar to using <code>Object.class</code> parameterization,
* and is equivalent to calling:
*<pre>
* typeFactory.constructMapLikeType(collectionClass, typeFactory.unknownType(), typeFactory.unknownType());
*<pre>
*<p>
* This method should only be used if parameterization is completely unavailable.
*/
public MapLikeType constructRawMapLikeType(Class<?> mapClass) {
return MapLikeType.construct(mapClass, unknownType(), unknownType());
}
/*
/**********************************************************
/* Actual factory methods
/**********************************************************
*/
/**
* @param context Mapping of formal parameter declarations (for generic
* types) into actual types
*/
protected JavaType _fromClass(Class<?> clz, TypeBindings context)
{
// Very first thing: small set of core types we know well:
if (clz == String.class) return CORE_TYPE_STRING;
if (clz == Boolean.TYPE) return CORE_TYPE_BOOL;
if (clz == Integer.TYPE) return CORE_TYPE_INT;
if (clz == Long.TYPE) return CORE_TYPE_LONG;
// Barring that, we may have recently constructed an instance:
ClassKey key = new ClassKey(clz);
JavaType result = _typeCache.get(key); // ok, cache object is synced
if (result != null) {
return result;
}
// If context was needed, weed do:
/*
if (context == null) {
context = new TypeBindings(this, cls);
}
*/
// First: do we have an array type?
if (clz.isArray()) {
result = ArrayType.construct(_constructType(clz.getComponentType(), null), null, null);
/* Also: although enums can also be fully resolved, there's little
* point in doing so (T extends Enum<T>) etc.
*/
} else if (clz.isEnum()) {
result = new SimpleType(clz);
/* Maps and Collections aren't quite as hot; problem is, due
* to type erasure we often do not know typing and can only assume
* base Object
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>.
*/
} else if (Map.class.isAssignableFrom(clz)) {
result = _mapType(clz);
} else if (Collection.class.isAssignableFrom(clz)) {
result = _collectionType(clz);
} else {
// 29-Sep-2014, tatu: We may want to pre-resolve well-known generic types
if (Map.Entry.class.isAssignableFrom(clz)) {
JavaType[] pts = this.findTypeParameters(clz, Map.Entry.class);
JavaType kt, vt;
if (pts == null || pts.length != 2) {
kt = vt = unknownType();
} else {
kt = pts[0];
vt = pts[1];
}
result = constructSimpleType(clz, Map.Entry.class, new JavaType[] { kt, vt });
} else {
result = new SimpleType(clz);
}
}
_typeCache.put(key, result); // cache object syncs
return result;
}
/**
* Method used by {@link TypeParser} when generics-aware version
* is constructed.
*/
protected JavaType _fromParameterizedClass(Class<?> clz, List<JavaType> paramTypes)
{
if (clz.isArray()) { // ignore generics (should never have any)
return ArrayType.construct(_constructType(clz.getComponentType(), null), null, null);
}
if (clz.isEnum()) { // ditto for enums
return new SimpleType(clz);
}
if (Map.class.isAssignableFrom(clz)) {
// First: if we do have param types, use them
JavaType keyType, contentType;
if (paramTypes.size() > 0) {
keyType = paramTypes.get(0);
contentType = (paramTypes.size() >= 2) ?
paramTypes.get(1) : _unknownType();
return MapType.construct(clz, keyType, contentType);
}
return _mapType(clz);
}
if (Collection.class.isAssignableFrom(clz)) {
if (paramTypes.size() >= 1) {
return CollectionType.construct(clz, paramTypes.get(0));
}
return _collectionType(clz);
}
if (paramTypes.size() == 0) {
return new SimpleType(clz);
}
// Hmmh. Does this actually occur?
JavaType[] pt = paramTypes.toArray(new JavaType[paramTypes.size()]);
return constructSimpleType(clz, clz, pt);
}
/**
* This method deals
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> with parameterized types, that is,
* first class generic classes.
*/
protected JavaType _fromParamType(ParameterizedType type, TypeBindings context)
{
/* First: what is the actual base type? One odd thing
* is that 'getRawType' returns Type, not Class<?> as
* one might expect. But let's assume it is always of
* type Class: if not, need to add more code to resolve
* it to Class.
*/
Class<?> rawType = (Class<?>) type.getRawType();
Type[] args = type.getActualTypeArguments();
int paramCount = (args == null) ? 0 : args.length;
JavaType[] pt;
if (paramCount == 0) {
pt = NO_TYPES;
} else {
pt = new JavaType[paramCount];
for (int i = 0; i < paramCount; ++i) {
pt[i] = _constructType(args[i], context);
}
}
// Ok: Map or Collection?
if (Map.class.isAssignableFrom(rawType)) {
JavaType subtype = constructSimpleType(rawType, rawType, pt);
JavaType[] mapParams = findTypeParameters(subtype, Map.class);
if (mapParams.length != 2) {
throw new IllegalArgumentException("Could not find 2 type parameters for Map class "+rawType.getName()+" (found "+mapParams.length+")");
}
return MapType.construct(rawType, mapParams[0], mapParams[1]);
}
if (Collection.class.isAssignableFrom(rawType)) {
JavaType subtype = constructSimpleType(rawType, rawType, pt);
JavaType[] collectionParams = findTypeParameters(subtype, Collection.class);
if (collectionParams.length != 1) {
throw new IllegalArgumentException("Could not find 1 type parameter for Collection class "+rawType.getName()+" (found "+collectionParams.length+")");
}
// bounds ("... extends A & B"); and optimally we might
// want to choose the best match. Also, bounds are optional;
// but here we are lucky in that implicit "Object" is
// added as bounds if so.
// Either way let's just use the first bound, for now, and
// worry about better match later on if there is need.
/* 29-Jan-2010, tatu: One more problem are recursive types
* (T extends Comparable<T>). Need to add "placeholder"
* for resolution to catch those.
*/
context._addPlaceholder(name);
return _constructType(bounds[0], context);
}
protected JavaType _fromWildcard(WildcardType type, TypeBindings
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> context)
{
/* Similar to challenges with TypeVariable, we may have
* multiple upper bounds. But it is also possible that if
* upper bound defaults to Object, we might want to consider
* lower bounds instead.
*
* For now, we won't try anything more advanced; above is
* just for future reference.
*/
return _constructType(type.getUpperBounds()[0], context);
}
private JavaType _mapType(Class<?> rawClass)
{
JavaType[] typeParams = findTypeParameters(rawClass, Map.class);
// ok to have no types ("raw")
if (typeParams == null) {
return MapType.construct(rawClass, _unknownType(), _unknownType());
}
// but exactly 2 types if any found
if (typeParams.length != 2) {
throw new IllegalArgumentException("Strange Map type "+rawClass.getName()+": can not determine type parameters");
}
return MapType.construct(rawClass, typeParams[0], typeParams[1]);
}
private JavaType _collectionType(Class<?> rawClass)
{
JavaType[] typeParams = findTypeParameters(rawClass, Collection.class);
// ok to have no types ("raw")
if (typeParams == null) {
return CollectionType.construct(rawClass, _unknownType());
}
// but exactly 2 types if any found
if (typeParams.length != 1) {
throw new IllegalArgumentException("Strange Collection type "+rawClass.getName()+": can not determine type parameters");
}
return CollectionType.construct(rawClass, typeParams[0]);
}
protected JavaType _resolveVariableViaSubTypes(HierarchicType leafType, String variableName, TypeBindings bindings)
{
// can't resolve raw types; possible to have as-of-yet-unbound types too:
if (leafType != null && leafType.isGeneric()) {
TypeVariable<?>[] typeVariables = leafType.getRawClass().getTypeParameters();
for (int i = 0, len = typeVariables.length; i < len; ++i) {
TypeVariable<?> tv = typeVariables[i];
if (variableName.equals(tv.getName())) {
// further resolution needed?
Type type = leafType.asGeneric().getActualTypeArguments()[i];
if (type instanceof TypeVariable<?>) {
return _resolveVariableViaSubTypes(leafType.getSubType(), ((TypeVariable<?>) type).getName(), bindings);
}
// no we're good for the variable (but it may have parameterization of its own)
return _constructType(type, bindings);
}
}
}
return _unknownType();
}
protected Java
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Type _unknownType() {
return new SimpleType(Object.class);
}
/*
/**********************************************************
/* Helper methods
/**********************************************************
*/
/**
* Helper method used to find inheritance (implements, extends) path
* between given types, if one exists (caller generally checks before
* calling this method). Returned type represents given <b>subtype</b>,
* with supertype linkage extending to <b>supertype</b>.
*/
protected HierarchicType _findSuperTypeChain(Class<?> subtype, Class<?> supertype)
{
// If super-type is a class (not interface), bit simpler
if (supertype.isInterface()) {
return _findSuperInterfaceChain(subtype, supertype);
}
return _findSuperClassChain(subtype, supertype);
}
protected HierarchicType _findSuperClassChain(Type currentType, Class<?> target)
{
HierarchicType current = new HierarchicType(currentType);
Class<?> raw = current.getRawClass();
if (raw == target) {
return current;
}
// Otherwise, keep on going down the rat hole...
Type parent = raw.getGenericSuperclass();
if (parent != null) {
HierarchicType sup = _findSuperClassChain(parent, target);
if (sup != null) {
sup.setSubType(current);
current.setSuperType(sup);
return current;
}
}
return null;
}
protected HierarchicType _findSuperInterfaceChain(Type currentType, Class<?> target)
{
HierarchicType current = new HierarchicType(currentType);
Class<?> raw = current.getRawClass();
if (raw == target) {
return new HierarchicType(currentType);
}
// Otherwise, keep on going down the rat hole; first implemented interfaces
/* 16-Aug-2011, tatu: Minor optimization based on profiled hot spot; let's
* try caching certain commonly needed cases
*/
if (raw == HashMap.class) {
if (target == Map.class) {
return _hashMapSuperInterfaceChain(current);
}
}
if (raw == ArrayList.class) {
if (target == List.class) {
return _arrayListSuperInterfaceChain(current);
}
}
return _doFindSuperInterfaceChain(current, target);
}
protected HierarchicType _doFindSuperInterfaceChain(HierarchicType current, Class<?> target)
{
Class<?> raw = current.getRawClass();
Type[] parents = raw.getGenericInterfaces();
// as long as there are superclasses
// and unless we have already seen the type (<
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.*;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Currency;
import java.util.Locale;
import java.util.TimeZone;
import java.util.regex.Pattern;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.fasterxml.jackson.databind.util.ClassUtil;
/**
* Base class for simple deserializers that only accept JSON String
* values as the source.
*/
@SuppressWarnings("serial")
public abstract class FromStringDeserializer<T> extends StdScalarDeserializer<T>
{
public static Class<?>[] types() {
return new Class<?>[] {
File.class,
URL.class,
URI.class,
Class.class,
JavaType.class,
Currency.class,
Pattern.class,
Locale.class,
Charset.class,
TimeZone.class,
InetAddress.class,
InetSocketAddress.class,
};
}
/*
/**********************************************************
/* Deserializer implementations
/**********************************************************
*/
protected FromStringDeserializer(Class<?> vc) {
super(vc);
}
/**
* Factory method for trying to find a deserializer for one of supported
* types that have simple from-String serialization.
*/
public static Std findDeserializer(Class<?> rawType)
{
int kind = 0;
if (rawType == File.class) {
kind = Std.STD_FILE;
} else if (rawType == URL.class) {
kind = Std.STD_URL;
} else if (rawType == URI.class) {
kind = Std.STD_URI;
} else if (rawType == Class.class) {
kind = Std.STD_CLASS;
} else if (rawType == JavaType.class) {
kind = Std.STD_JAVA_TYPE;
} else if (rawType == Currency.class) {
kind = Std.STD_CURRENCY;
} else if (rawType == Pattern.class) {
kind = Std.STD_PATTERN;
} else if (rawType == Locale.class) {
kind = Std.STD_LOCALE;
} else if (rawType == Charset.class
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> ob = jp.getEmbeddedObject();
if (ob == null) {
return null;
}
if (_valueClass.isAssignableFrom(ob.getClass())) {
return (T) ob;
}
return _deserializeEmbedded(ob, ctxt);
}
throw ctxt.mappingException(_valueClass);
}
protected abstract T _deserialize(String value, DeserializationContext ctxt) throws IOException;
protected T _deserializeEmbedded(Object ob, DeserializationContext ctxt) throws IOException {
// default impl: error out
throw ctxt.mappingException("Don't know how to convert embedded Object of type "+ob.getClass().getName()+" into "+_valueClass.getName());
}
protected T _deserializeFromEmptyString() throws IOException {
return null;
}
/*
/**********************************************************
/* A general-purpose implementation
/**********************************************************
*/
/**
* "Chameleon" deserializer that works on simple types that are deserialized
* from a simple String.
*
* @since 2.4
*/
public static class Std extends FromStringDeserializer<Object>
{
private static final long serialVersionUID = 1;
public final static int STD_FILE = 1;
public final static int STD_URL = 2;
public final static int STD_URI = 3;
public final static int STD_CLASS = 4;
public final static int STD_JAVA_TYPE = 5;
public final static int STD_CURRENCY = 6;
public final static int STD_PATTERN = 7;
public final static int STD_LOCALE = 8;
public final static int STD_CHARSET = 9;
public final static int STD_TIME_ZONE = 10;
public final static int STD_INET_ADDRESS = 11;
public final static int STD_INET_SOCKET_ADDRESS = 12;
protected final int _kind;
protected Std(Class<?> valueType, int kind) {
super(valueType);
_kind = kind;
}
@Override
protected Object _deserialize(String value, DeserializationContext ctxt) throws IOException
{
switch (_kind) {
case STD_FILE:
return new File(value);
case STD_URL:
return new URL(value);
case STD_URI:
return URI.create(value);
case STD_CLASS:
try {
return ctxt.findClass(value);
} catch (Exception e) {
throw ctxt.instantiationException(_valueClass, ClassUtil.getRootCause(e));
}
case STD_JAVA_TYPE:
return ctxt.getTypeFactory().constructFromCanonical(value);
case STD_CURRENCY:
// will throw IAE if unknown:
return Currency.getInstance(value);
case STD_
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.exc;
import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonMappingException;
/**
* Specialized sub-class of {@link JsonMappingException}
* that is used when the underlying problem appears to be that
* of bad formatting of a value to deserialize.
*
* @since 2.1
*/
public class InvalidFormatException extends JsonMappingException
{
private static final long serialVersionUID = 1L; // silly Eclipse, warnings
/**
* Underlying value that could not be deserialized into
* target type, if available.
*/
protected final Object _value;
/**
* Intended target type (type-erased class) that value could not
* be deserialized into, if known.
*/
protected final Class<?> _targetType;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public InvalidFormatException(String msg,
Object value, Class<?> targetType)
{
super(msg);
_value = value;
_targetType = targetType;
}
public InvalidFormatException(String msg, JsonLocation loc,
Object value, Class<?> targetType)
{
super(msg, loc);
_value = value;
_targetType = targetType;
}
public static InvalidFormatException from(JsonParser jp, String msg,
Object value, Class<?> targetType)
{
return new InvalidFormatException(msg, jp.getTokenLocation(),
value, targetType);
}
/*
/**********************************************************
/* Additional accessors
/**********************************************************
*/
/**
* Accessor for checking source value (String, Number usually) that could not
* be deserialized into target type ({@link #getTargetType}).
* Note that value may not be available, depending on who throws the exception
* and when.
*/
public Object getValue() {
return _value;
}
/**
* Accessor for checking target type of value ({@link #getValue} that failed
* to deserialize.
* Note that type may not be available, depending on who throws the exception
* and when.
*/
public Class<?> getTargetType() {
return _targetType;
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return _managedProperty.getAnnotation(acls);
}
@Override public AnnotatedMember getMember() { return _managedProperty.getMember(); }
/*
/**********************************************************
/* Overridden methods
/**********************************************************
*/
@Override
public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt, Object instance)
throws IOException, JsonProcessingException {
set(instance, _managedProperty.deserialize(jp, ctxt));
}
@Override
public Object deserializeSetAndReturn(JsonParser jp, DeserializationContext ctxt, Object instance)
throws IOException, JsonProcessingException {
return setAndReturn(instance, deserialize(jp, ctxt));
}
@Override
public final void set(Object instance, Object value) throws IOException {
setAndReturn(instance, value);
}
@Override
public Object setAndReturn(Object instance, Object value) throws IOException
{
/* 04-Feb-2014, tatu: As per [#390], it may be necessary to switch the
* ordering of forward/backward references, and start with back ref.
*/
if (value != null) {
if (_isContainer) { // ok, this gets ugly... but has to do for now
if (value instanceof Object[]) {
for (Object ob : (Object[]) value) {
if (ob != null) { _backProperty.set(ob, instance); }
}
} else if (value instanceof Collection<?>) {
for (Object ob : (Collection<?>) value) {
if (ob != null) { _backProperty.set(ob, instance); }
}
} else if (value instanceof Map<?,?>) {
for (Object ob : ((Map<?,?>) value).values()) {
if (ob != null) { _backProperty.set(ob, instance); }
}
} else {
throw new IllegalStateException("Unsupported container type ("+value.getClass().getName()
+") when resolving reference '"+_referenceName+"'");
}
} else {
_backProperty.set(value, instance);
}
}
// and then the forward reference itself
return _managedProperty.setAndReturn(instance, value);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
/**
* Base class for deserializers that handle types that are serialized
* as JSON scalars (non-structured, i.e. non-Object, non-Array, values).
*/
public abstract class StdScalarDeserializer<T> extends StdDeserializer<T>
{
private static final long serialVersionUID = 1L;
protected StdScalarDeserializer(Class<?> vc) { super(vc); }
protected StdScalarDeserializer(JavaType valueType) { super(valueType); }
// since 2.5
protected StdScalarDeserializer(StdScalarDeserializer<?> src) { super(src); }
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException {
return typeDeserializer.deserializeTypedFromScalar(jp, ctxt);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> type of values this deserializer produces.
* Note that this information is not guaranteed to be exact -- it
* may be a more generic (super-type) -- but it should not be
* incorrect (return a non-related type).
*<p>
* Default implementation will return null, which means almost same
* same as returning <code>Object.class</code> would; that is, that
* nothing is known about handled type.
*<p>
* @since 2.3
*/
public Class<?> handledType() { return null; }
/**
* Method that can be called to determine value to be used for
* representing null values (values deserialized when JSON token
* is {@link JsonToken#VALUE_NULL}). Usually this is simply
* Java null, but for some types (especially primitives) it may be
* necessary to use non-null values.
*<p>
* Note that deserializers are allowed to call this just once and
* then reuse returned value; that is, method is not guaranteed to
* be called once for each conversion.
*<p>
* Default implementation simply returns null.
*/
public T getNullValue() { return null; }
/**
* Method called to determine value to be used for "empty" values
* (most commonly when deserializing from empty JSON Strings).
* Usually this is same as {@link #getNullValue} (which in turn
* is usually simply Java null), but it can be overridden
* for types. Or, if type should never be converted from empty
* String, method can also throw an exception.
*<p>
* Default implementation simple calls {@link #getNullValue} and
* returns value.
*/
public T getEmptyValue() { return getNullValue(); }
/**
* Method that will
* either return null to indicate that type being deserializers
* has no concept of properties; or a collection of identifiers
* for which <code>toString</code> will give external property
* name.
* This is only to be used for error reporting and diagnostics
* purposes (most commonly, to accompany "unknown property"
* exception).
*
* @since 2.0
*/
public Collection<Object> getKnownPropertyNames() {
return null;
}
/**
* Method called to see if deserializer instance is cachable and
* usable for other properties of same type (type for which instance
* was created).
*<p>
* Note that cached instances are still resolved on per-property basis,
* if instance implements {@link com.fasterxml.jackson.databind.deser.ResolvableDeserializer}:
* cached instance is just as the base. This means that in most cases it is safe to
* cache instances;
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>T> src)
{
super(src);
_converter = src._converter;
_delegateType = src._delegateType;
_delegateDeserializer = src._delegateDeserializer;
}
/**
* Method used for creating resolved contextual instances. Must be
* overridden when sub-classing.
*/
protected StdDelegatingDeserializer<T> withDelegate(Converter<Object,T> converter,
JavaType delegateType, JsonDeserializer<?> delegateDeserializer)
{
if (getClass() != StdDelegatingDeserializer.class) {
throw new IllegalStateException("Sub-class "+getClass().getName()+" must override 'withDelegate'");
}
return new StdDelegatingDeserializer<T>(converter, delegateType, delegateDeserializer);
}
/*
/**********************************************************
/* Contextualization
/**********************************************************
*/
@Override
public void resolve(DeserializationContext ctxt)
throws JsonMappingException
{
if (_delegateDeserializer != null && _delegateDeserializer instanceof ResolvableDeserializer) {
((ResolvableDeserializer) _delegateDeserializer).resolve(ctxt);
}
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
throws JsonMappingException
{
// First: if already got serializer to delegate to, contextualize it:
if (_delegateDeserializer != null) {
JsonDeserializer<?> deser = ctxt.handleSecondaryContextualization(_delegateDeserializer,
property, _delegateType);
if (deser != _delegateDeserializer) {
return withDelegate(_converter, _delegateType, deser);
}
return this;
}
// Otherwise: figure out what is the fully generic delegate type, then find deserializer
JavaType delegateType = _converter.getInputType(ctxt.getTypeFactory());
return withDelegate(_converter, delegateType,
ctxt.findContextualValueDeserializer(delegateType, property));
}
/*
/**********************************************************
/* Accessors
/**********************************************************
*/
@Override
public JsonDeserializer<?> getDelegatee() {
return _delegateDeserializer;
}
@Override
public Class<?> handledType() {
return _delegateDeserializer.handledType();
}
/*
/**********************************************************
/* Serialization
/**********************************************************
*/
@Override
public T deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
Object delegateValue = _delegateDeserializer.deserialize(jp, ctxt);
if (delegateValue == null) {
return null;
}
return convertValue(delegateValue);
}
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException, JsonProcessingException
{
/* 03-Oct-2012, tatu: This is actually unlikely to work ok... but for now,
* let's give
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.impl;
import java.io.IOException;
import java.util.Iterator;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.ContainerSerializer;
import com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase;
@SuppressWarnings("serial")
@JacksonStdImpl
public class IteratorSerializer
extends AsArraySerializerBase<Iterator<?>>
{
public IteratorSerializer(JavaType elemType, boolean staticTyping, TypeSerializer vts,
BeanProperty property)
{
super(Iterator.class, elemType, staticTyping, vts, property, null);
}
public IteratorSerializer(IteratorSerializer src,
BeanProperty property, TypeSerializer vts, JsonSerializer<?> valueSerializer)
{
super(src, property, vts, valueSerializer);
}
@Override
public boolean isEmpty(SerializerProvider prov, Iterator<?> value) {
return (value == null) || !value.hasNext();
}
@Override
public boolean hasSingleElement(Iterator<?> value) {
// no really good way to determine (without consuming iterator), so:
return false;
}
@Override
public ContainerSerializer<?> _withValueTypeSerializer(TypeSerializer vts) {
return new IteratorSerializer(_elementType, _staticTyping, vts, _property);
}
@Override
public IteratorSerializer withResolved(BeanProperty property,
TypeSerializer vts, JsonSerializer<?> elementSerializer) {
return new IteratorSerializer(this, property, vts, elementSerializer);
}
@Override
public final void serialize(Iterator<?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException
{
if (provider.isEnabled(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED) && hasSingleElement(value)) {
serializeContents(value, jgen, provider);
return;
}
jgen.writeStartArray();
serializeContents(value, jgen, provider);
jgen.writeEndArray();
}
@Override
public void serializeContents(Iterator<?> value, JsonGenerator jgen, SerializerProvider provider)
throws IOException
{
if (value.hasNext()) {
final TypeSerializer typeSer = _valueTypeSerializer;
JsonSerializer<Object> prevSerializer = null;
Class<?> prevClass = null;
do {
Object elem = value.next();
if (elem == null) {
provider.defaultSerializeNull(jgen);
continue;
}
JsonSerializer<Object> currSerializer = _elementSerializer;
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> if (currSerializer == null) {
// Minor optimization to avoid most lookups:
Class<?> cc = elem.getClass();
if (cc == prevClass) {
currSerializer = prevSerializer;
} else {
currSerializer = provider.findValueSerializer(cc, _property);
prevSerializer = currSerializer;
prevClass = cc;
}
}
if (typeSer == null) {
currSerializer.serialize(elem, jgen, provider);
} else {
currSerializer.serializeWithType(elem, jgen, provider, typeSer);
}
} while (value.hasNext());
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>, serDef));
}
// And then, handling of unwrapping
NameTransformer unwrapper = _annotationIntrospector.findUnwrappingNameTransformer(am);
if (unwrapper != null) {
bpw = bpw.unwrappingWriter(unwrapper);
}
return bpw;
}
/*
/**********************************************************
/* Helper methods; annotation access
/**********************************************************
*/
/**
* Method that will try to determine statically defined type of property
* being serialized, based on annotations (for overrides), and alternatively
* declared type (if static typing for serialization is enabled).
* If neither can be used (no annotations, dynamic typing), returns null.
*/
protected JavaType findSerializationType(Annotated a, boolean useStaticTyping, JavaType declaredType)
{
// [JACKSON-120]: Check to see if serialization type is fixed
Class<?> serClass = _annotationIntrospector.findSerializationType(a);
if (serClass != null) {
// Must be a super type to be usable
Class<?> rawDeclared = declaredType.getRawClass();
if (serClass.isAssignableFrom(rawDeclared)) {
declaredType = declaredType.widenBy(serClass);
} else {
/* 18-Nov-2010, tatu: Related to fixing [JACKSON-416], an issue with such
* check is that for deserialization more specific type makes sense;
* and for serialization more generic. But alas JAXB uses but a single
* annotation to do both... Hence, we must just discard type, as long as
* types are related
*/
if (!rawDeclared.isAssignableFrom(serClass)) {
throw new IllegalArgumentException("Illegal concrete-type annotation for method '"+a.getName()+"': class "+serClass.getName()+" not a super-type of (declared) class "+rawDeclared.getName());
}
/* 03-Dec-2010, tatu: Actually, ugh, to resolve [JACKSON-415] may further relax this
* and actually accept subtypes too for serialization. Bit dangerous in theory
* but need to trust user here...
*/
declaredType = _config.constructSpecializedType(declaredType, serClass);
}
useStaticTyping = true;
}
// Should not have to do static method but...
JavaType secondary = BasicSerializerFactory.modifySecondaryTypesByAnnotation(_config, a, declaredType);
if (secondary != declaredType) {
useStaticTyping = true;
declaredType = secondary;
}
/* [JACKSON-114]: if using static typing, declared type is known
* to be the type...
*/
JsonSerialize.Typing
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> typing = _annotationIntrospector.findSerializationTyping(a);
if (typing != null && typing != JsonSerialize.Typing.DEFAULT_TYPING) {
useStaticTyping = (typing == JsonSerialize.Typing.STATIC);
}
return useStaticTyping ? declaredType : null;
}
/*
/**********************************************************
/* Helper methods for default value handling
/**********************************************************
*/
protected Object getDefaultBean()
{
if (_defaultBean == null) {
/* If we can fix access rights, we should; otherwise non-public
* classes or default constructor will prevent instantiation
*/
_defaultBean = _beanDesc.instantiateBean(_config.canOverrideAccessModifiers());
if (_defaultBean == null) {
Class<?> cls = _beanDesc.getClassInfo().getAnnotated();
throw new IllegalArgumentException("Class "+cls.getName()+" has no default constructor; can not instantiate default bean value to support 'properties=JsonSerialize.Inclusion.NON_DEFAULT' annotation");
}
}
return _defaultBean;
}
protected Object getDefaultValue(String name, AnnotatedMember member)
{
Object defaultBean = getDefaultBean();
try {
return member.getValue(defaultBean);
} catch (Exception e) {
return _throwWrapped(e, name, defaultBean);
}
}
/*
/**********************************************************
/* Helper methods for exception handling
/**********************************************************
*/
protected Object _throwWrapped(Exception e, String propName, Object defaultBean)
{
Throwable t = e;
while (t.getCause() != null) {
t = t.getCause();
}
if (t instanceof Error) throw (Error) t;
if (t instanceof RuntimeException) throw (RuntimeException) t;
throw new IllegalArgumentException("Failed to get property '"+propName+"' of default "+defaultBean.getClass().getName()+" instance");
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import java.lang.reflect.Method;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.EnumResolver;
/**
* Deserializer class that can deserialize instances of
* specified Enum class from Strings and Integers.
*/
public class EnumDeserializer
extends StdScalarDeserializer<Enum<?>>
{
private static final long serialVersionUID = 1L;
protected final EnumResolver<?> _resolver;
public EnumDeserializer(EnumResolver<?> res)
{
super(Enum.class);
_resolver = res;
}
/**
* Factory method used when Enum instances are to be deserialized
* using a creator (static factory method)
*
* @return Deserializer based on given factory method, if type was suitable;
* null if type can not be used
*/
public static JsonDeserializer<?> deserializerForCreator(DeserializationConfig config,
Class<?> enumClass, AnnotatedMethod factory)
{
// note: caller has verified there's just one arg; but we must verify its type
Class<?> paramClass = factory.getRawParameterType(0);
if (config.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(factory.getMember());
}
return new FactoryBasedDeserializer(enumClass, factory, paramClass);
}
/*
/**********************************************************
/* Default JsonDeserializer implementation
/**********************************************************
*/
/**
* Because of costs associated with constructing Enum resolvers,
* let's cache instances by default.
*/
@Override
public boolean isCachable() { return true; }
@Override
public Enum<?> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
JsonToken curr = jp.getCurrentToken();
// Usually should just get string value:
if (curr == JsonToken.VALUE_STRING || curr == JsonToken.FIELD_NAME) {
String name = jp.getText();
Enum<?> result = _resolver.findEnum(name);
if (result == null) {
return _deserializeAltString(jp, ctxt, name);
}
return result;
}
// But let's consider int acceptable as well (if within ordinal range)
if (curr == JsonToken.VALUE_NUMBER_INT) {
// ... unless told not to do that. :-) (as per [JACKSON-
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>S_FOR_ENUMS)) {
throw ctxt.mappingException("Not allowed to deserialize Enum value out of JSON number (disable DeserializationConfig.DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS to allow)");
}
}
/*
/**********************************************************
/* Additional helper classes
/**********************************************************
*/
/**
* Deserializer that uses a single-String static factory method
* for locating Enum values by String id.
*/
protected static class FactoryBasedDeserializer
extends StdDeserializer<Object>
implements ContextualDeserializer
{
private static final long serialVersionUID = 1;
// Marker type; null if String expected; otherwise numeric wrapper
protected final Class<?> _inputType;
protected final Method _factory;
protected final JsonDeserializer<?> _deser;
public FactoryBasedDeserializer(Class<?> cls, AnnotatedMethod f,
Class<?> inputType)
{
super(cls);
_factory = f.getAnnotated();
_inputType = inputType;
_deser = null;
}
protected FactoryBasedDeserializer(FactoryBasedDeserializer base,
JsonDeserializer<?> deser) {
super(base._valueClass);
_inputType = base._inputType;
_factory = base._factory;
_deser = deser;
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
BeanProperty property)
throws JsonMappingException
{
if ((_deser == null) && (_inputType != String.class)) {
return new FactoryBasedDeserializer(this,
ctxt.findContextualValueDeserializer(ctxt.constructType(_inputType), property));
}
return this;
}
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
Object value;
if (_deser != null) {
value = _deser.deserialize(jp, ctxt);
} else {
value = jp.getValueAsString();
}
try {
return _factory.invoke(_valueClass, value);
} catch (Exception e) {
Throwable t = ClassUtil.getRootCause(e);
if (t instanceof IOException) {
throw (IOException) t;
}
throw ctxt.instantiationException(_valueClass, t);
}
}
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException {
if (_deser == null) { // String never has type info
return deserialize(jp, ctxt);
}
return typeDeserializer.deserializeTypedFromAny(jp, ctxt);
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.exc;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.databind.JsonMappingException;
/**
* Base class for {@link JsonMappingException}s that are specifically related
* to problems related to binding an individual property.
*
* @since 2.3
*/
@SuppressWarnings("serial")
public abstract class PropertyBindingException
extends JsonMappingException
{
/**
* Class that does not contain mapping for the unrecognized property.
*/
protected final Class<?> _referringClass;
/**
*<p>
* Note: redundant information since it is also included in the
* reference path.
*/
protected final String _propertyName;
/**
* Set of ids of properties that are known for the type, if this
* can be statically determined.
*/
protected final Collection<Object> _propertyIds;
/**
* Lazily constructed description of known properties, used for
* constructing actual message if and as needed.
*/
protected transient String _propertiesAsString;
protected PropertyBindingException(String msg, JsonLocation loc,
Class<?> referringClass, String propName,
Collection<Object> propertyIds)
{
super(msg, loc);
_referringClass = referringClass;
_propertyName = propName;
_propertyIds = propertyIds;
}
/*
/**********************************************************
/* Overrides
/**********************************************************
*/
/**
* Somewhat arbitrary limit, but let's try not to create uselessly
* huge error messages
*/
private final static int MAX_DESC_LENGTH = 1000;
@Override
public String getMessageSuffix()
{
String suffix = _propertiesAsString;
if (suffix == null && _propertyIds != null) {
StringBuilder sb = new StringBuilder(100);
int len = _propertyIds.size();
if (len == 1) {
sb.append(" (one known property: \"");
sb.append(String.valueOf(_propertyIds.iterator().next()));
sb.append('"');
} else {
sb.append(" (").append(len).append(" known properties: ");
Iterator<Object> it = _propertyIds.iterator();
while (it.hasNext()) {
sb.append('"');
sb.append(String.valueOf(it.next()));
sb.append('"');
// one other thing: limit max length
if (sb.length() > MAX_DESC_LENGTH) {
sb.append(" [truncated]");
break;
}
if (it.hasNext()) {
sb.append(", ");
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> }
}
sb.append("])");
_propertiesAsString = suffix = sb.toString();
}
return suffix;
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
/**
* Method for accessing type (class) that is missing definition to allow
* binding of the unrecognized property.
*/
public Class<?> getReferringClass() {
return _referringClass;
}
/**
* Convenience method for accessing logical property name that could
* not be mapped. Note that it is the last path reference in the
* underlying path.
*/
public String getPropertyName() {
return _propertyName;
}
public Collection<Object> getKnownPropertyIds()
{
if (_propertyIds == null) {
return null;
}
return Collections.unmodifiableCollection(_propertyIds);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
/**
* Intermediate base class for serializers used for serializing
* types that contain element(s) of other types, such as arrays,
* {@link java.util.Collection}s (<code>Lists</code>, <code>Sets</code>
* etc) and {@link java.util.Map}s and iterable things
* ({@link java.util.Iterator}s).
*/
@SuppressWarnings("serial")
public abstract class ContainerSerializer<T>
extends StdSerializer<T>
{
/*
/**********************************************************
/* Construction, initialization
/**********************************************************
*/
protected ContainerSerializer(Class<T> t) {
super(t);
}
/**
* @since 2.5
*/
protected ContainerSerializer(JavaType fullType) {
super(fullType);
}
/**
* Alternate constructor that is (alas!) needed to work
* around kinks of generic type handling
*
* @param t
*/
protected ContainerSerializer(Class<?> t, boolean dummy) {
super(t, dummy);
}
protected ContainerSerializer(ContainerSerializer<?> src) {
super(src._handledType, false);
}
/**
* Factory(-like) method that can be used to construct a new container
* serializer that uses specified {@link TypeSerializer} for decorating
* contained values with additional type information.
*
* @param vts Type serializer to use for contained values; can be null,
* in which case 'this' serializer is returned as is
* @return Serializer instance that uses given type serializer for values if
* that is possible (or if not, just 'this' serializer)
*/
public ContainerSerializer<?> withValueTypeSerializer(TypeSerializer vts) {
if (vts == null) return this;
return _withValueTypeSerializer(vts);
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
/**
* Accessor for finding declared (static) element type for
* type this serializer is used for.
*/
public abstract JavaType getContentType();
/**
* Accessor for serializer used for serializing contents
* (List and array elements, Map values etc) of the
* container for which this serializer is used, if it is
* known statically.
* Note that for dynamic types this may return null; if so,
* caller has to instead use {@link #getContentType()} and
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.type;
import java.util.*;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.util.ClassUtil;
/**
* Simple recursive-descent parser for parsing canonical {@link JavaType}
* representations and constructing type instances.
*
* @author tatu
*/
public class TypeParser
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
protected final TypeFactory _factory;
public TypeParser(TypeFactory f) {
_factory = f;
}
public JavaType parse(String canonical)
throws IllegalArgumentException
{
canonical = canonical.trim();
MyTokenizer tokens = new MyTokenizer(canonical);
JavaType type = parseType(tokens);
// must be end, now
if (tokens.hasMoreTokens()) {
throw _problem(tokens, "Unexpected tokens after complete type");
}
return type;
}
protected JavaType parseType(MyTokenizer tokens)
throws IllegalArgumentException
{
if (!tokens.hasMoreTokens()) {
throw _problem(tokens, "Unexpected end-of-string");
}
Class<?> base = findClass(tokens.nextToken(), tokens);
// either end (ok, non generic type), or generics
if (tokens.hasMoreTokens()) {
String token = tokens.nextToken();
if ("<".equals(token)) {
return _factory._fromParameterizedClass(base, parseTypes(tokens));
}
// can be comma that separates types, or closing '>'
tokens.pushBack(token);
}
return _factory._fromClass(base, null);
}
protected List<JavaType> parseTypes(MyTokenizer tokens)
throws IllegalArgumentException
{
ArrayList<JavaType> types = new ArrayList<JavaType>();
while (tokens.hasMoreTokens()) {
types.add(parseType(tokens));
if (!tokens.hasMoreTokens()) break;
String token = tokens.nextToken();
if (">".equals(token)) return types;
if (!",".equals(token)) {
throw _problem(tokens, "Unexpected token '"+token+"', expected ',' or '>')");
}
}
throw _problem(tokens, "Unexpected end-of-string");
}
protected Class<?> findClass(String className, MyTokenizer tokens)
{
try {
return ClassUtil.findClass(className);
} catch (Exception e) {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
throw _problem(tokens, "Can not locate class '"+className+"', problem: "+e.getMessage());
}
}
protected IllegalArgumentException _problem(MyTokenizer tokens, String msg)
{
return new IllegalArgumentException("
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonFormat.Shape;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonIntegerFormatVisitor;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonStringFormatVisitor;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.util.EnumValues;
/**
* Standard serializer used for {@link java.lang.Enum} types.
*<p>
* Based on {@link StdScalarSerializer} since the JSON value is
* scalar (String).
*
* @author tatu
*/
@JacksonStdImpl
public class EnumSerializer
extends StdScalarSerializer<Enum<?>>
implements ContextualSerializer
{
private static final long serialVersionUID = 1L;
/**
* This map contains pre-resolved values (since there are ways
* to customize actual String constants to use) to use as
* serializations.
*/
protected final EnumValues _values;
/**
* Flag that is set if we statically know serialization choice
* between index and textual format (null if it needs to be dynamically
* checked).
*
* @since 2.1
*/
protected final Boolean _serializeAsIndex;
/*
/**********************************************************
/* Construction, initialization
/**********************************************************
*/
/**
* @deprecated Since 2.1
*/
@Deprecated
public EnumSerializer(EnumValues v) {
this(v, null);
}
public EnumSerializer(EnumValues v, Boolean serializeAsIndex)
{
super(Enum.class, false);
_values = v;
_serializeAsIndex = serializeAsIndex;
}
/**
* Factory method used by {@link com.fasterxml.jackson.databind.ser.BasicSerializerFactory}
* for constructing serializer instance of Enum types.
*
* @since 2.1
*/
@SuppressWarnings("unchecked")
public static EnumSerializer construct(Class<?> enumClass, SerializationConfig config,
BeanDescription beanDesc, JsonFormat
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>.Value format)
{
// [JACKSON-212]: If toString() is to be used instead, leave EnumValues null
EnumValues v = EnumValues.construct(config, (Class<Enum<?>>) enumClass);
Boolean serializeAsIndex = _isShapeWrittenUsingIndex(enumClass, format, true);
return new EnumSerializer(v, serializeAsIndex);
}
/**
* To support some level of per-property configuration, we will need
* to make things contextual. We are limited to "textual vs index"
* choice here, however.
*/
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException
{
if (property != null) {
JsonFormat.Value format = prov.getAnnotationIntrospector().findFormat((Annotated) property.getMember());
if (format != null) {
Boolean serializeAsIndex = _isShapeWrittenUsingIndex(property.getType().getRawClass(), format, false);
if (serializeAsIndex != _serializeAsIndex) {
return new EnumSerializer(_values, serializeAsIndex);
}
}
}
return this;
}
/*
/**********************************************************
/* Extended API for Jackson databind core
/**********************************************************
*/
public EnumValues getEnumValues() { return _values; }
/*
/**********************************************************
/* Actual serialization
/**********************************************************
*/
@Override
public final void serialize(Enum<?> en, JsonGenerator jgen, SerializerProvider provider)
throws IOException
{
// [JACKSON-684]: serialize as index?
if (_serializeAsIndex(provider)) {
jgen.writeNumber(en.ordinal());
return;
}
jgen.writeString(_values.serializedValueFor(en));
}
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint)
{
// [JACKSON-684]: serialize as index?
if (_serializeAsIndex(provider)) {
return createSchemaNode("integer", true);
}
ObjectNode objectNode = createSchemaNode("string", true);
if (typeHint != null) {
JavaType type = provider.constructType(typeHint);
if (type.isEnumType()) {
ArrayNode enumNode = objectNode.putArray("enum");
for (SerializableString value : _values.values()) {
enumNode.add(value.getValue());
}
}
}
return objectNode;
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
throws JsonMappingException
{
// [JACKSON-684]: serialize as index?
if (_serializeAsIndex(visitor.getProvider())) {
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> JsonIntegerFormatVisitor v2 = visitor.expectIntegerFormat(typeHint);
if (v2 != null) { // typically serialized as a small number (byte or int)
v2.numberType(JsonParser.NumberType.INT);
}
} else {
JsonStringFormatVisitor stringVisitor = visitor.expectStringFormat(typeHint);
if (typeHint != null && stringVisitor != null) {
if (typeHint.isEnumType()) {
Set<String> enums = new LinkedHashSet<String>();
for (SerializableString value : _values.values()) {
enums.add(value.getValue());
}
stringVisitor.enumTypes(enums);
}
}
}
}
/*
/**********************************************************
/* Helper methods
/**********************************************************
*/
protected final boolean _serializeAsIndex(SerializerProvider provider)
{
if (_serializeAsIndex != null) {
return _serializeAsIndex.booleanValue();
}
return provider.isEnabled(SerializationFeature.WRITE_ENUMS_USING_INDEX);
}
/**
* Helper method called to check whether
*/
protected static Boolean _isShapeWrittenUsingIndex(Class<?> enumClass,
JsonFormat.Value format, boolean fromClass)
{
JsonFormat.Shape shape = (format == null) ? null : format.getShape();
if (shape == null) {
return null;
}
if (shape == Shape.ANY || shape == Shape.SCALAR) { // i.e. "default", check dynamically
return null;
}
if (shape == Shape.STRING) {
return Boolean.FALSE;
}
// 01-Oct-2014, tatu: For convenience, consider "as-array" to also mean 'yes, use index')
if (shape.isNumeric() || (shape == Shape.ARRAY)) {
return Boolean.TRUE;
}
throw new IllegalArgumentException("Unsupported serialization shape ("+shape+") for Enum "+enumClass.getName()
+", not supported as "
+ (fromClass? "class" : "property")
+" annotation");
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.type;
import com.fasterxml.jackson.databind.JavaType;
/**
* Type that represents "true" Java Map types.
*/
public final class MapType extends MapLikeType
{
private static final long serialVersionUID = -811146779148281500L;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
private MapType(Class<?> mapType, JavaType keyT, JavaType valueT,
Object valueHandler, Object typeHandler, boolean asStatic) {
super(mapType, keyT, valueT, valueHandler, typeHandler, asStatic);
}
public static MapType construct(Class<?> rawType, JavaType keyT, JavaType valueT) {
// nominally component types will be just Object.class
return new MapType(rawType, keyT, valueT, null, null, false);
}
@Override
protected JavaType _narrow(Class<?> subclass) {
return new MapType(subclass, _keyType, _valueType,
_valueHandler, _typeHandler, _asStatic);
}
@Override
public JavaType narrowContentsBy(Class<?> contentClass)
{
// Can do a quick check first:
if (contentClass == _valueType.getRawClass()) {
return this;
}
return new MapType(_class, _keyType, _valueType.narrowBy(contentClass),
_valueHandler, _typeHandler, _asStatic);
}
@Override
public JavaType widenContentsBy(Class<?> contentClass)
{
if (contentClass == _valueType.getRawClass()) {
return this;
}
return new MapType(_class, _keyType, _valueType.widenBy(contentClass),
_valueHandler, _typeHandler, _asStatic);
}
@Override
public JavaType narrowKey(Class<?> keySubclass)
{
// Can do a quick check first:
if (keySubclass == _keyType.getRawClass()) {
return this;
}
return new MapType(_class, _keyType.narrowBy(keySubclass), _valueType,
_valueHandler, _typeHandler, _asStatic);
}
@Override
public JavaType widenKey(Class<?> keySubclass)
{
// Can do a quick check first:
if (keySubclass == _keyType.getRawClass()) {
return this;
}
return new MapType(_class, _keyType.widenBy(keySubclass), _valueType,
_valueHandler, _typeHandler, _asStatic);
}
@Override
public MapType withTypeHandler(Object h) {
return new MapType
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>(_class, _keyType, _valueType, _valueHandler, h, _asStatic);
}
@Override
public MapType withContentTypeHandler(Object h)
{
return new MapType(_class, _keyType, _valueType.withTypeHandler(h),
_valueHandler, _typeHandler, _asStatic);
}
@Override
public MapType withValueHandler(Object h) {
return new MapType(_class, _keyType, _valueType, h, _typeHandler, _asStatic);
}
@Override
public MapType withContentValueHandler(Object h) {
return new MapType(_class, _keyType, _valueType.withValueHandler(h),
_valueHandler, _typeHandler, _asStatic);
}
@Override
public MapType withStaticTyping() {
if (_asStatic) {
return this;
}
return new MapType(_class, _keyType.withStaticTyping(), _valueType.withStaticTyping(),
_valueHandler, _typeHandler, true);
}
/*
/**********************************************************
/* Overridden accessors
/**********************************************************
*/
@Override
public Class<?> getParameterSource() {
return java.util.Map.class;
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
@Override
public MapType withKeyTypeHandler(Object h)
{
return new MapType(_class, _keyType.withTypeHandler(h), _valueType,
_valueHandler, _typeHandler, _asStatic);
}
@Override
public MapType withKeyValueHandler(Object h) {
return new MapType(_class, _keyType.withValueHandler(h), _valueType,
_valueHandler, _typeHandler, _asStatic);
}
/*
/**********************************************************
/* Standard methods
/**********************************************************
*/
@Override
public String toString()
{
return "[map type; class "+_class.getName()+", "+_keyType+" -> "+_valueType+"]";
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonIntegerFormatVisitor;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonNumberFormatVisitor;
/**
* As a fallback, we may need to use this serializer for other
* types of {@link Number}s: both custom types and "big" numbers
* like {@link BigInteger} and {@link BigDecimal}.
*/
@JacksonStdImpl
@SuppressWarnings("serial")
public class NumberSerializer
extends StdScalarSerializer<Number>
{
/**
* Static instance that is only to be used for {@link java.lang.Number}.
*/
public final static NumberSerializer instance = new NumberSerializer(Number.class);
protected final boolean _isInt;
@Deprecated // since 2.5
public NumberSerializer() {
super(Number.class);
_isInt = false;
}
/**
* @since 2.5
*/
public NumberSerializer(Class<? extends Number> rawType) {
super(rawType, false);
// since this will NOT be constructed for Integer or Long, only case is:
_isInt = (rawType == BigInteger.class);
}
@Override
public void serialize(Number value, JsonGenerator jgen, SerializerProvider provider) throws IOException
{
// should mostly come in as one of these two:
if (value instanceof BigDecimal) {
jgen.writeNumber((BigDecimal) value);
} else if (value instanceof BigInteger) {
jgen.writeNumber((BigInteger) value);
/* These shouldn't match (as there are more specific ones),
* but just to be sure:
*/
} else if (value instanceof Integer) {
jgen.writeNumber(value.intValue());
} else if (value instanceof Long) {
jgen.writeNumber(value.longValue());
} else if (value instanceof Double) {
jgen.writeNumber(value.doubleValue());
} else if (value instanceof Float) {
jgen.writeNumber(value.floatValue());
} else if ((value instanceof Byte) || (value instanceof Short)) {
jgen.writeNumber(value.intValue()); // doesn't need to be cast to smaller numbers
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
} else {
// We'll have to use fallback "untyped" number write method
jgen.writeNumber(value.toString());
}
}
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint) {
return createSchemaNode(_isInt ? "integer" : "number", true);
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException
{
if (_isInt) {
JsonIntegerFormatVisitor v2 = visitor.expectIntegerFormat(typeHint);
if (v2 != null) {
v2.numberType(JsonParser.NumberType.BIG_INTEGER);
}
} else {
JsonNumberFormatVisitor v2 = visitor.expectNumberFormat(typeHint);
if (v2 != null) {
Class<?> h = handledType();
if (h == BigDecimal.class) {
v2.numberType(JsonParser.NumberType.BIG_DECIMAL);
} // otherwise it's for Number... anything we could do there?
}
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.exc;
import java.util.*;
import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonMappingException;
/**
* Specialized {@link JsonMappingException} sub-class specifically used
* to indicate problems due to encountering a JSON property that could
* not be mapped to an Object property (via getter, constructor argument
* or field).
*/
public class UnrecognizedPropertyException
extends PropertyBindingException
{
private static final long serialVersionUID = 1L;
public UnrecognizedPropertyException(String msg, JsonLocation loc,
Class<?> referringClass, String propName,
Collection<Object> propertyIds)
{
super(msg, loc, referringClass, propName, propertyIds);
}
/**
* Factory method used for constructing instances of this exception type.
*
* @param jp Underlying parser used for reading input being used for data-binding
* @param fromObjectOrClass Reference to either instance of problematic type (
* if available), or if not, type itself
* @param propertyName Name of unrecognized property
* @param propertyIds (optional, null if not available) Set of properties that
* type would recognize, if completely known: null if set can not be determined.
*/
public static UnrecognizedPropertyException from(JsonParser jp,
Object fromObjectOrClass, String propertyName,
Collection<Object> propertyIds)
{
if (fromObjectOrClass == null) {
throw new IllegalArgumentException();
}
Class<?> ref;
if (fromObjectOrClass instanceof Class<?>) {
ref = (Class<?>) fromObjectOrClass;
} else {
ref = fromObjectOrClass.getClass();
}
String msg = "Unrecognized field \""+propertyName+"\" (class "+ref.getName()+"), not marked as ignorable";
UnrecognizedPropertyException e = new UnrecognizedPropertyException(msg,
jp.getCurrentLocation(), ref, propertyName, propertyIds);
// but let's also ensure path includes this last (missing) segment
e.prependPath(fromObjectOrClass, propertyName);
return e;
}
/**
* @deprecated Since 2.3, use {@link #getPropertyName} instead.
*/
@Deprecated // since 2.3
public String getUnrecognizedPropertyName() {
return getPropertyName();
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>resolvedForwardReference("Unresolved forward references for: ");
}
for (Iterator<Referring> iterator = roid.referringProperties(); iterator.hasNext(); ) {
Referring referring = iterator.next();
exception.addUnresolvedId(roid.getKey().key, referring.getBeanType(), referring.getLocation());
}
}
}
if (exception != null) {
throw exception;
}
}
/*
/**********************************************************
/* Abstract methods impls, other factory methods
/**********************************************************
*/
@SuppressWarnings("unchecked")
@Override
public JsonDeserializer<Object> deserializerInstance(Annotated ann, Object deserDef)
throws JsonMappingException
{
if (deserDef == null) {
return null;
}
JsonDeserializer<?> deser;
if (deserDef instanceof JsonDeserializer) {
deser = (JsonDeserializer<?>) deserDef;
} else {
/* Alas, there's no way to force return type of "either class
* X or Y" -- need to throw an exception after the fact
*/
if (!(deserDef instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector returned deserializer definition of type "+deserDef.getClass().getName()+"; expected type JsonDeserializer or Class<JsonDeserializer> instead");
}
Class<?> deserClass = (Class<?>)deserDef;
// there are some known "no class" markers to consider too:
if (deserClass == JsonDeserializer.None.class || ClassUtil.isBogusClass(deserClass)) {
return null;
}
if (!JsonDeserializer.class.isAssignableFrom(deserClass)) {
throw new IllegalStateException("AnnotationIntrospector returned Class "+deserClass.getName()+"; expected Class<JsonDeserializer>");
}
HandlerInstantiator hi = _config.getHandlerInstantiator();
deser = (hi == null) ? null : hi.deserializerInstance(_config, ann, deserClass);
if (deser == null) {
deser = (JsonDeserializer<?>) ClassUtil.createInstance(deserClass,
_config.canOverrideAccessModifiers());
}
}
// First: need to resolve
if (deser instanceof ResolvableDeserializer) {
((ResolvableDeserializer) deser).resolve(this);
}
return (JsonDeserializer<Object>) deser;
}
@Override
public final KeyDeserializer keyDeserializerInstance(Annotated ann, Object deserDef)
throws JsonMappingException
{
if (deserDef == null) {
return null;
}
KeyDeserializer deser;
if (deserDef instanceof KeyDeserializer) {
deser = (KeyDeserializer) deserDef;
} else {
if (!(deserDef instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector returned key deserializer definition of
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> type "
+deserDef.getClass().getName()
+"; expected type KeyDeserializer or Class<KeyDeserializer> instead");
}
Class<?> deserClass = (Class<?>)deserDef;
// there are some known "no class" markers to consider too:
if (deserClass == KeyDeserializer.None.class || ClassUtil.isBogusClass(deserClass)) {
return null;
}
if (!KeyDeserializer.class.isAssignableFrom(deserClass)) {
throw new IllegalStateException("AnnotationIntrospector returned Class "+deserClass.getName()
+"; expected Class<KeyDeserializer>");
}
HandlerInstantiator hi = _config.getHandlerInstantiator();
deser = (hi == null) ? null : hi.keyDeserializerInstance(_config, ann, deserClass);
if (deser == null) {
deser = (KeyDeserializer) ClassUtil.createInstance(deserClass,
_config.canOverrideAccessModifiers());
}
}
// First: need to resolve
if (deser instanceof ResolvableDeserializer) {
((ResolvableDeserializer) deser).resolve(this);
}
return deser;
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
/**
* Fluent factory method used for constructing a blueprint instance
* with different factory
*/
public abstract DefaultDeserializationContext with(DeserializerFactory factory);
/**
* Method called to create actual usable per-deserialization
* context instance.
*/
public abstract DefaultDeserializationContext createInstance(
DeserializationConfig config, JsonParser jp, InjectableValues values);
/*
/**********************************************************
/* And then the concrete implementation class
/**********************************************************
*/
/**
* Actual full concrete implementation
*/
public final static class Impl extends DefaultDeserializationContext
{
private static final long serialVersionUID = 1L;
/**
* Default constructor for a blueprint object, which will use the standard
* {@link DeserializerCache}, given factory.
*/
public Impl(DeserializerFactory df) {
super(df, null);
}
protected Impl(Impl src,
DeserializationConfig config, JsonParser jp, InjectableValues values) {
super(src, config, jp, values);
}
protected Impl(Impl src) { super(src); }
protected Impl(Impl src, DeserializerFactory factory) {
super(src, factory);
}
@Override
public DefaultDeserializationContext copy() {
if (getClass() != Impl.class) {
return super.copy();
}
return new Impl(this);
}
@Override
public DefaultDeserializationContext createInstance(DeserializationConfig config,
JsonParser jp, InjectableValues values) {
return new Impl(this, config, jp, values);
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.annotation;
import java.lang.annotation.*;
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
/**
* Annotation that can be used to explicitly define custom resolver
* used for handling serialization and deserialization of type information,
* needed for handling of polymorphic types (or sometimes just for linking
* abstract types to concrete types)
*<p>
* NOTE: since 2.4, applicable to properties as well (should have been long time
* ago, but problem only found then)
*/
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@com.fasterxml.jackson.annotation.JacksonAnnotation
public @interface JsonTypeResolver
{
/**
* Defines implementation class of {@link TypeResolverBuilder} which is used to construct
* actual {@link com.fasterxml.jackson.databind.jsontype.TypeDeserializer} and {@link com.fasterxml.jackson.databind.jsontype.TypeDeserializer}
* instances that handle reading and writing addition type information needed to support polymorphic
* deserialization.
*/
public Class<? extends TypeResolverBuilder<?>> value();
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
public boolean hasKnownClassAnnotations() {
return _classInfo.hasAnnotations();
}
@Override
public Annotations getClassAnnotations() {
return _classInfo.getAnnotations();
}
@Override
public TypeBindings bindingsForBeanType()
{
if (_bindings == null) {
_bindings = new TypeBindings(_config.getTypeFactory(), _type);
}
return _bindings;
}
@Override
public JavaType resolveType(java.lang.reflect.Type jdkType) {
if (jdkType == null) {
return null;
}
return bindingsForBeanType().resolveType(jdkType);
}
@Override
public AnnotatedConstructor findDefaultConstructor() {
return _classInfo.getDefaultConstructor();
}
@Override
public AnnotatedMethod findAnySetter() throws IllegalArgumentException
{
if (_anySetterMethod != null) {
/* Also, let's be somewhat strict on how field name is to be
* passed; String, Object make sense, others not
* so much.
*/
/* !!! 18-May-2009, tatu: how about enums? Can add support if
* requested; easy enough for devs to add support within
* method.
*/
Class<?> type = _anySetterMethod.getRawParameterType(0);
if (type != String.class && type != Object.class) {
throw new IllegalArgumentException("Invalid 'any-setter' annotation on method "+_anySetterMethod.getName()+"(): first argument not of type String or Object, but "+type.getName());
}
}
return _anySetterMethod;
}
@Override
public Map<Object, AnnotatedMember> findInjectables() {
return _injectables;
}
@Override
public List<AnnotatedConstructor> getConstructors() {
return _classInfo.getConstructors();
}
@Override
public Object instantiateBean(boolean fixAccess)
{
AnnotatedConstructor ac = _classInfo.getDefaultConstructor();
if (ac == null) {
return null;
}
if (fixAccess) {
ac.fixAccess();
}
try {
return ac.getAnnotated().newInstance();
} catch (Exception e) {
Throwable t = e;
while (t.getCause() != null) {
t = t.getCause();
}
if (t instanceof Error) throw (Error) t;
if (t instanceof RuntimeException) throw (RuntimeException) t;
throw new IllegalArgumentException("Failed to instantiate bean of type "+_classInfo.getAnnotated().getName()+": ("+t.getClass().getName()+") "+t.getMessage(), t);
}
}
/*
/**********************************************************
/* Simple accessors, extended
/**********************************************************
*/
@Override
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
public AnnotatedMethod findMethod(String name, Class<?>[] paramTypes) {
return _classInfo.findMethod(name, paramTypes);
}
/*
/**********************************************************
/* General per-class annotation introspection
/**********************************************************
*/
@Override
public JsonFormat.Value findExpectedFormat(JsonFormat.Value defValue)
{
if (_annotationIntrospector != null) {
JsonFormat.Value v = _annotationIntrospector.findFormat(_classInfo);
if (v != null) {
return v;
}
}
return defValue;
}
/*
/**********************************************************
/* Introspection for serialization
/**********************************************************
*/
@Override
public Converter<Object,Object> findSerializationConverter()
{
if (_annotationIntrospector == null) {
return null;
}
return _createConverter(_annotationIntrospector.findSerializationConverter(_classInfo));
}
/**
* Method for determining whether null properties should be written
* out for a Bean of introspected type. This is based on global
* feature (lowest priority, passed as argument)
* and per-class annotation (highest priority).
*/
@Override
public JsonInclude.Include findSerializationInclusion(JsonInclude.Include defValue) {
if (_annotationIntrospector == null) {
return defValue;
}
return _annotationIntrospector.findSerializationInclusion(_classInfo, defValue);
}
@Override
public JsonInclude.Include findSerializationInclusionForContent(JsonInclude.Include defValue) {
if (_annotationIntrospector == null) {
return defValue;
}
return _annotationIntrospector.findSerializationInclusionForContent(_classInfo, defValue);
}
/**
* Method used to locate the method of introspected class that
* implements {@link com.fasterxml.jackson.annotation.JsonAnyGetter}.
* If no such method exists null is returned.
* If more than one are found, an exception is thrown.
*/
@Override
public AnnotatedMember findAnyGetter() throws IllegalArgumentException
{
if (_anyGetter != null) {
/* For now let's require a Map; in future can add support for other
* types like perhaps Iterable<Map.Entry>?
*/
Class<?> type = _anyGetter.getRawType();
if (!Map.class.isAssignableFrom(type)) {
throw new IllegalArgumentException("Invalid 'any-getter' annotation on method "+_anyGetter.getName()+"(): return type is not instance of java.util.Map");
}
}
return _anyGetter;
}
@Override
public Map<String,AnnotatedMember> findBackReferenceProperties()
{
HashMap<String,AnnotatedMember> result = null;
// boolean has
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Ignored = (_ignoredPropertyNames != null);
for (BeanPropertyDefinition property : _properties) {
/* 23-Sep-2014, tatu: As per [Databind#426], we _should_ try to avoid
* calling accessor, as it triggers exception from seeming conflict.
* But the problem is that _ignoredPropertyNames here only contains
* ones ignored on per-property annotations, but NOT class annotations...
* so commented out part does not work, alas
*/
/*
if (hasIgnored && _ignoredPropertyNames.contains(property.getName())) {
continue;
}
*/
AnnotatedMember am = property.getMutator();
if (am == null) {
continue;
}
AnnotationIntrospector.ReferenceProperty refDef = _annotationIntrospector.findReferenceType(am);
if (refDef != null && refDef.isBackReference()) {
if (result == null) {
result = new HashMap<String,AnnotatedMember>();
}
String refName = refDef.getName();
if (result.put(refName, am) != null) {
throw new IllegalArgumentException("Multiple back-reference properties with name '"+refName+"'");
}
}
}
return result;
}
/*
/**********************************************************
/* Introspection for deserialization, factories
/**********************************************************
*/
@Override
public List<AnnotatedMethod> getFactoryMethods()
{
// must filter out anything that clearly is not a factory method
List<AnnotatedMethod> candidates = _classInfo.getStaticMethods();
if (candidates.isEmpty()) {
return candidates;
}
ArrayList<AnnotatedMethod> result = new ArrayList<AnnotatedMethod>();
for (AnnotatedMethod am : candidates) {
if (isFactoryMethod(am)) {
result.add(am);
}
}
return result;
}
@Override
public Constructor<?> findSingleArgConstructor(Class<?>... argTypes)
{
for (AnnotatedConstructor ac : _classInfo.getConstructors()) {
// This list is already filtered to only include accessible
/* (note: for now this is a redundant check; but in future
* that may change; thus leaving here for now)
*/
if (ac.getParameterCount() == 1) {
Class<?> actArg = ac.getRawParameterType(0);
for (Class<?> expArg : argTypes) {
if (expArg == actArg) {
return ac.getAnnotated();
}
}
}
}
return null;
}
@Override
public Method findFactoryMethod(Class<?>... expArgTypes)
{
// So, of all single-arg static methods:
for (AnnotatedMethod am : _class
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Info.getStaticMethods()) {
if (isFactoryMethod(am)) {
// And must take one of expected arg types (or supertype)
Class<?> actualArgType = am.getRawParameterType(0);
for (Class<?> expArgType : expArgTypes) {
// And one that matches what we would pass in
if (actualArgType.isAssignableFrom(expArgType)) {
return am.getAnnotated();
}
}
}
}
return null;
}
protected boolean isFactoryMethod(AnnotatedMethod am)
{
/* First: return type must be compatible with the introspected class
* (i.e. allowed to be sub-class, although usually is the same
* class)
*/
Class<?> rt = am.getRawReturnType();
if (!getBeanClass().isAssignableFrom(rt)) {
return false;
}
/* Also: must be a recognized factory method, meaning:
* (a) marked with @JsonCreator annotation, or
* (b) "valueOf" (at this point, need not be public)
*/
if (_annotationIntrospector.hasCreatorAnnotation(am)) {
return true;
}
final String name = am.getName();
if ("valueOf".equals(name)) {
return true;
}
// [Issue#208] Also accept "fromString()", if takes String or CharSequence
if ("fromString".equals(name)) {
if (1 == am.getParameterCount()) {
Class<?> cls = am.getRawParameterType(0);
if (cls == String.class || CharSequence.class.isAssignableFrom(cls)) {
return true;
}
}
}
return false;
}
/**
* @deprecated Since 2.4, use <code>findCreatorParameterNames()</code> instead.
*/
@Deprecated
public List<String> findCreatorPropertyNames()
{
List<PropertyName> params = findCreatorParameterNames();
if (params.isEmpty()) {
return Collections.emptyList();
}
List<String> result = new ArrayList<String>(params.size());
for (PropertyName name : params) {
result.add(name.getSimpleName());
}
return result;
}
/**
* @deprecated Since 2.5, does not seem to be used at all.
*/
@Deprecated
public List<PropertyName> findCreatorParameterNames()
{
for (int i = 0; i < 2; ++i) {
List<? extends AnnotatedWithParams> l = (i == 0)
? getConstructors() : getFactoryMethods();
for (AnnotatedWithParams creator : l) {
int argCount = creator.getParameterCount();
if (argCount < 1) continue;
PropertyName name =
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> _findCreatorPropertyName(creator.getParameter(0));
if (name == null || name.isEmpty()) {
continue;
}
List<PropertyName> names = new ArrayList<PropertyName>();
names.add(name);
for (int p = 1; p < argCount; ++p) {
name = _findCreatorPropertyName(creator.getParameter(p));
names.add(name);
}
return names;
}
}
return Collections.emptyList();
}
protected PropertyName _findCreatorPropertyName(AnnotatedParameter param)
{
PropertyName name = _annotationIntrospector.findNameForDeserialization(param);
if (name == null || name.isEmpty()) {
String str = _annotationIntrospector.findImplicitPropertyName(param);
if (str != null && !str.isEmpty()) {
name = new PropertyName(str);
}
}
return name;
}
/*
/**********************************************************
/* Introspection for deserialization, other
/**********************************************************
*/
@Override
public Class<?> findPOJOBuilder()
{
return (_annotationIntrospector == null) ?
null : _annotationIntrospector.findPOJOBuilder(_classInfo);
}
@Override
public JsonPOJOBuilder.Value findPOJOBuilderConfig()
{
return (_annotationIntrospector == null) ?
null : _annotationIntrospector.findPOJOBuilderConfig(_classInfo);
}
@Override
public Converter<Object,Object> findDeserializationConverter()
{
if (_annotationIntrospector == null) {
return null;
}
return _createConverter(_annotationIntrospector.findDeserializationConverter(_classInfo));
}
/*
/**********************************************************
/* Helper methods for field introspection
/**********************************************************
*/
/**
* @param ignoredProperties (optional) names of properties to ignore;
* any fields that would be recognized as one of these properties
* is ignored.
* @param forSerialization If true, will collect serializable property
* fields; if false, deserializable
*
* @return Ordered Map with logical property name as key, and
* matching field as value.
*/
public LinkedHashMap<String,AnnotatedField> _findPropertyFields(
Collection<String> ignoredProperties, boolean forSerialization)
{
LinkedHashMap<String,AnnotatedField> results = new LinkedHashMap<String,AnnotatedField>();
for (BeanPropertyDefinition property : _properties) {
AnnotatedField f = property.getField();
if (f != null) {
String name = property.getName();
if (ignoredProperties != null) {
if (ignoredProperties.contains(name)) {
continue;
}
}
results.put(name,
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> f);
}
}
return results;
}
/*
/**********************************************************
/* Helper methods, other
/**********************************************************
*/
@SuppressWarnings("unchecked")
public Converter<Object,Object> _createConverter(Object converterDef)
{
if (converterDef == null) {
return null;
}
if (converterDef instanceof Converter<?,?>) {
return (Converter<Object,Object>) converterDef;
}
if (!(converterDef instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector returned Converter definition of type "
+converterDef.getClass().getName()+"; expected type Converter or Class<Converter> instead");
}
Class<?> converterClass = (Class<?>)converterDef;
// there are some known "no class" markers to consider too:
if (converterClass == Converter.None.class || ClassUtil.isBogusClass(converterClass)) {
return null;
}
if (!Converter.class.isAssignableFrom(converterClass)) {
throw new IllegalStateException("AnnotationIntrospector returned Class "
+converterClass.getName()+"; expected Class<Converter>");
}
HandlerInstantiator hi = _config.getHandlerInstantiator();
Converter<?,?> conv = (hi == null) ? null : hi.converterInstance(_config, _classInfo, converterClass);
if (conv == null) {
conv = (Converter<?,?>) ClassUtil.createInstance(converterClass,
_config.canOverrideAccessModifiers());
}
return (Converter<Object,Object>) conv;
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
*/
public SettableBeanProperty withSimpleName(String simpleName) {
PropertyName n = (_propName == null)
? new PropertyName(simpleName) : _propName.withSimpleName(simpleName);
return (n == _propName) ? this : withName(n);
}
@Deprecated // since 2.3 -- use 'withSimpleName' instead if need be
public SettableBeanProperty withName(String simpleName) {
return withName(new PropertyName(simpleName));
}
public void setManagedReferenceName(String n) {
_managedReferenceName = n;
}
public void setObjectIdInfo(ObjectIdInfo objectIdInfo) {
_objectIdInfo = objectIdInfo;
}
public void setViews(Class<?>[] views) {
if (views == null) {
_viewMatcher = null;
} else {
_viewMatcher = ViewMatcher.construct(views);
}
}
/**
* Method used to assign index for property.
*/
public void assignIndex(int index) {
if (_propertyIndex != -1) {
throw new IllegalStateException("Property '"+getName()+"' already had index ("+_propertyIndex+"), trying to assign "+index);
}
_propertyIndex = index;
}
/*
/**********************************************************
/* BeanProperty impl
/**********************************************************
*/
@Override
public final String getName() {
return _propName.getSimpleName();
}
@Override
public PropertyName getFullName() {
return _propName;
}
@Override
public boolean isRequired() { return _metadata.isRequired(); }
@Override
public PropertyMetadata getMetadata() { return _metadata; }
@Override
public JavaType getType() { return _type; }
@Override
public PropertyName getWrapperName() {
return _wrapperName;
}
@Override
public abstract <A extends Annotation> A getAnnotation(Class<A> acls);
@Override
public abstract AnnotatedMember getMember();
@Override
public <A extends Annotation> A getContextAnnotation(Class<A> acls) {
return _contextAnnotations.get(acls);
}
@Override
public void depositSchemaProperty(JsonObjectFormatVisitor objectVisitor)
throws JsonMappingException
{
if (isRequired()) {
objectVisitor.property(this);
} else {
objectVisitor.optionalProperty(this);
}
}
/*
/**********************************************************
/* Accessors
/**********************************************************
*/
protected final Class<?> getDeclaringClass() {
return getMember().getDeclaringClass();
}
public String getManagedReferenceName() { return _managedReferenceName; }
public ObjectIdInfo getObjectIdInfo() { return _objectIdInfo; }
public
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> boolean hasValueDeserializer() {
return (_valueDeserializer != null) && (_valueDeserializer != MISSING_VALUE_DESERIALIZER);
}
public boolean hasValueTypeDeserializer() { return (_valueTypeDeserializer != null); }
public JsonDeserializer<Object> getValueDeserializer() {
JsonDeserializer<Object> deser = _valueDeserializer;
if (deser == MISSING_VALUE_DESERIALIZER) {
return null;
}
return deser;
}
public TypeDeserializer getValueTypeDeserializer() { return _valueTypeDeserializer; }
public boolean visibleInView(Class<?> activeView) {
return (_viewMatcher == null) || _viewMatcher.isVisibleForView(activeView);
}
public boolean hasViews() { return _viewMatcher != null; }
/**
* Method for accessing unique index of this property; indexes are
* assigned once all properties of a {@link BeanDeserializer} have
* been collected.
*
* @return Index of this property
*/
public int getPropertyIndex() { return _propertyIndex; }
/**
* Method for accessing index of the creator property: for other
* types of properties will simply return -1.
*
* @since 2.1
*/
public int getCreatorIndex() { return -1; }
/**
* Accessor for id of injectable value, if this bean property supports
* value injection.
*/
public Object getInjectableValueId() { return null; }
/*
/**********************************************************
/* Public API
/**********************************************************
*/
/**
* Method called to deserialize appropriate value, given parser (and
* context), and set it using appropriate mechanism.
* Pre-condition is that passed parser must point to the first token
* that should be consumed to produce the value (the only value for
* scalars, multiple for Objects and Arrays).
*/
public abstract void deserializeAndSet(JsonParser p,
DeserializationContext ctxt, Object instance) throws IOException;
/**
* Alternative to {@link #deserializeAndSet} that returns
* either return value of setter method called (if one is),
* or null to indicate that no return value is available.
* Mostly used to support Builder style deserialization.
*
* @since 2.0
*/
public abstract Object deserializeSetAndReturn(JsonParser p,
DeserializationContext ctxt, Object instance) throws IOException;
/**
* Method called to assign given value to this property, on
* specified Object.
*<p>
* Note: this is an optional operation, not supported by all
* implementations, creator-backed properties for example do not
* support this method.
*/
public abstract void set(Object instance, Object value) throws IOException;
/**
* Method called to assign given value to this property, on
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import java.util.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
/**
* Deserializer for {@link EnumMap} values.
* <p>
* Note: casting within this class is all messed up -- just could not figure out a way
* to properly deal with recursive definition of "EnumMap<K extends Enum<K>, V>
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public class EnumMapDeserializer
extends ContainerDeserializerBase<EnumMap<?,?>>
implements ContextualDeserializer
{
private static final long serialVersionUID = 1;
protected final JavaType _mapType;
protected final Class<?> _enumClass;
protected KeyDeserializer _keyDeserializer;
protected JsonDeserializer<Object> _valueDeserializer;
/**
* If value instances have polymorphic type information, this
* is the type deserializer that can handle it
*/
protected final TypeDeserializer _valueTypeDeserializer;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public EnumMapDeserializer(JavaType mapType, KeyDeserializer keyDeserializer, JsonDeserializer<?> valueDeser, TypeDeserializer valueTypeDeser)
{
super(mapType);
_mapType = mapType;
_enumClass = mapType.getKeyType().getRawClass();
_keyDeserializer = keyDeserializer;
_valueDeserializer = (JsonDeserializer<Object>) valueDeser;
_valueTypeDeserializer = valueTypeDeser;
}
public EnumMapDeserializer withResolved(KeyDeserializer keyDeserializer, JsonDeserializer<?> valueDeserializer, TypeDeserializer valueTypeDeser)
{
if ((keyDeserializer == _keyDeserializer) && (valueDeserializer == _valueDeserializer) && (valueTypeDeser == _valueTypeDeserializer)) {
return this;
}
return new EnumMapDeserializer(_mapType, keyDeserializer, valueDeserializer, _valueTypeDeserializer);
}
/**
* Method called to finalize setup of this deserializer,
* when it is known for which property deserializer is needed for.
*/
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException
{
// note: instead of finding key deserializer, with enums we actually
// work with regular deserializers (less code duplication; but not
// quite as clean as it ought to be)
KeyDeserializer kd = _keyDeserializer;
if (kd == null) {
kd = ctxt.findKeyDeserializer(_mapType.getKeyType(), property);
}
Json
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.introspect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
* Helper class needed to be able to efficiently access class
* member functions ({@link Method}s and {@link Constructor}s)
* in {@link java.util.Map}s.
*/
public final class MemberKey
{
final static Class<?>[] NO_CLASSES = new Class<?>[0];
final String _name;
final Class<?>[] _argTypes;
public MemberKey(Method m)
{
this(m.getName(), m.getParameterTypes());
}
public MemberKey(Constructor<?> ctor)
{
this("", ctor.getParameterTypes());
}
public MemberKey(String name, Class<?>[] argTypes)
{
_name = name;
_argTypes = (argTypes == null) ? NO_CLASSES : argTypes;
}
@Override
public String toString() {
return _name + "(" + _argTypes.length+"-args)";
}
@Override
public int hashCode()
{
return _name.hashCode() + _argTypes.length;
}
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != getClass()) {
return false;
}
MemberKey other = (MemberKey) o;
if (!_name.equals(other._name)) {
return false;
}
Class<?>[] otherArgs = other._argTypes;
int len = _argTypes.length;
if (otherArgs.length != len) {
return false;
}
for (int i = 0; i < len; ++i) {
Class<?> type1 = otherArgs[i];
Class<?> type2 = _argTypes[i];
if (type1 == type2) {
continue;
}
/* 23-Feb-2009, tatu: Are there any cases where we would have to
* consider some narrowing conversions or such? For now let's
* assume exact type match is enough
*/
/* 07-Apr-2009, tatu: Indeed there are (see [JACKSON-97]).
* This happens with generics when a bound is specified.
* I hope this works; check here must be transitive
*/
/* 14-Oct-2014, tatu: No, doing that is wrong. Conflicts may (and will) be
* handled at a later point; trying to change definition of equality
* will just cause problems like [jackson-core#
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.util;
import java.lang.reflect.*;
import java.util.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
public final class ClassUtil
{
/*
/**********************************************************
/* Methods that deal with inheritance
/**********************************************************
*/
/**
* Method that will find all sub-classes and implemented interfaces
* of a given class or interface. Classes are listed in order of
* precedence, starting with the immediate super-class, followed by
* interfaces class directly declares to implemented, and then recursively
* followed by parent of super-class and so forth.
* Note that <code>Object.class</code> is not included in the list
* regardless of whether <code>endBefore</code> argument is defined or not.
*
* @param endBefore Super-type to NOT include in results, if any; when
* encountered, will be ignored (and no super types are checked).
*/
public static List<Class<?>> findSuperTypes(Class<?> cls, Class<?> endBefore) {
return findSuperTypes(cls, endBefore, new ArrayList<Class<?>>(8));
}
public static List<Class<?>> findSuperTypes(Class<?> cls, Class<?> endBefore, List<Class<?>> result) {
_addSuperTypes(cls, endBefore, result, false);
return result;
}
private static void _addSuperTypes(Class<?> cls, Class<?> endBefore, Collection<Class<?>> result, boolean addClassItself) {
if (cls == endBefore || cls == null || cls == Object.class) { return; }
if (addClassItself) {
if (result.contains(cls)) { // already added, no need to check supers
return;
}
result.add(cls);
}
for (Class<?> intCls : cls.getInterfaces()) {
_addSuperTypes(intCls, endBefore, result, true);
}
_addSuperTypes(cls.getSuperclass(), endBefore, result, true);
}
/*
/**********************************************************
/* Class type detection methods
/**********************************************************
*/
/**
* @return Null if class might be a bean; type String (that identifies
* why it's not a bean) if not
*/
public static String canBeABeanType(Class<?> type)
{
// First: language constructs that ain't beans:
if (type.isAnnotation()) {
return "annotation";
}
if (type.isArray()) {
return "array";
}
if (type.isEnum()) {
return "enum";
}
if (type.isPrimitive()) {
return "primitive";
}
// Any
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>thing else? Seems valid, then
return null;
}
public static String isLocalType(Class<?> type, boolean allowNonStatic)
{
/* As per [JACKSON-187], GAE seems to throw SecurityExceptions
* here and there... and GAE itself has a bug, too
* (see []). Bah. So we need to catch some wayward exceptions on GAE
*/
try {
// one more: method locals, anonymous, are not good:
if (type.getEnclosingMethod() != null) {
return "local/anonymous";
}
/* But how about non-static inner classes? Can't construct
* easily (theoretically, we could try to check if parent
* happens to be enclosing... but that gets convoluted)
*/
if (!allowNonStatic) {
if (type.getEnclosingClass() != null) {
if (!Modifier.isStatic(type.getModifiers())) {
return "non-static member class";
}
}
}
}
catch (SecurityException e) { }
catch (NullPointerException e) { }
return null;
}
/**
* Method for finding enclosing class for non-static inner classes
*/
public static Class<?> getOuterClass(Class<?> type)
{
// as above, GAE has some issues...
try {
// one more: method locals, anonymous, are not good:
if (type.getEnclosingMethod() != null) {
return null;
}
if (!Modifier.isStatic(type.getModifiers())) {
return type.getEnclosingClass();
}
} catch (SecurityException e) { }
catch (NullPointerException e) { }
return null;
}
/**
* Helper method used to weed out dynamic Proxy types; types that do
* not expose concrete method API that we could use to figure out
* automatic Bean (property) based serialization.
*/
public static boolean isProxyType(Class<?> type)
{
// As per [Issue#57], should NOT disqualify JDK proxy:
/*
// Then: well-known proxy (etc) classes
if (Proxy.isProxyClass(type)) {
return true;
}
*/
String name = type.getName();
// Hibernate uses proxies heavily as well:
if (name.startsWith("net.sf.cglib.proxy.")
|| name.startsWith("org.hibernate.proxy.")) {
return true;
}
// Not one of known proxies, nope:
return false;
}
/**
* Helper method that checks if given class is a concrete one;
* that is, not an interface or abstract class.
*/
public static boolean isConcrete(Class<?> type)
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
{
int mod = type.getModifiers();
return (mod & (Modifier.INTERFACE | Modifier.ABSTRACT)) == 0;
}
public static boolean isConcrete(Member member)
{
int mod = member.getModifiers();
return (mod & (Modifier.INTERFACE | Modifier.ABSTRACT)) == 0;
}
public static boolean isCollectionMapOrArray(Class<?> type)
{
if (type.isArray()) return true;
if (Collection.class.isAssignableFrom(type)) return true;
if (Map.class.isAssignableFrom(type)) return true;
return false;
}
/*
/**********************************************************
/* Type name handling methods
/**********************************************************
*/
/**
* Helper method used to construct appropriate description
* when passed either type (Class) or an instance; in latter
* case, class of instance is to be used.
*/
public static String getClassDescription(Object classOrInstance)
{
if (classOrInstance == null) {
return "unknown";
}
Class<?> cls = (classOrInstance instanceof Class<?>) ?
(Class<?>) classOrInstance : classOrInstance.getClass();
return cls.getName();
}
/*
/**********************************************************
/* Class loading
/**********************************************************
*/
public static Class<?> findClass(String className) throws ClassNotFoundException
{
// [JACKSON-597]: support primitive types (and void)
if (className.indexOf('.') < 0) {
if ("int".equals(className)) return Integer.TYPE;
if ("long".equals(className)) return Long.TYPE;
if ("float".equals(className)) return Float.TYPE;
if ("double".equals(className)) return Double.TYPE;
if ("boolean".equals(className)) return Boolean.TYPE;
if ("byte".equals(className)) return Byte.TYPE;
if ("char".equals(className)) return Character.TYPE;
if ("short".equals(className)) return Short.TYPE;
if ("void".equals(className)) return Void.TYPE;
}
// Two-phase lookup: first using context ClassLoader; then default
Throwable prob = null;
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader != null) {
try {
return Class.forName(className, true, loader);
} catch (Exception e) {
prob = getRootCause(e);
}
}
try {
return Class.forName(className);
} catch (Exception e) {
if (prob == null) {
prob = getRootCause(e);
}
}
if (prob instanceof RuntimeException) {
throw (RuntimeException) prob;
}
throw new ClassNotFoundException(prob.getMessage(), prob);
}
/*
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> /**********************************************************
/* Method type detection methods
/**********************************************************
*/
public static boolean hasGetterSignature(Method m)
{
// First: static methods can't be getters
if (Modifier.isStatic(m.getModifiers())) {
return false;
}
// Must take no args
Class<?>[] pts = m.getParameterTypes();
if (pts != null && pts.length != 0) {
return false;
}
// Can't be a void method
if (Void.TYPE == m.getReturnType()) {
return false;
}
// Otherwise looks ok:
return true;
}
/*
/**********************************************************
/* Exception handling
/**********************************************************
*/
/**
* Method that can be used to find the "root cause", innermost
* of chained (wrapped) exceptions.
*/
public static Throwable getRootCause(Throwable t)
{
while (t.getCause() != null) {
t = t.getCause();
}
return t;
}
/**
* Method that will unwrap root causes of given Throwable, and throw
* the innermost {@link Exception} or {@link Error} as is.
* This is useful in cases where mandatory wrapping is added, which
* is often done by Reflection API.
*/
public static void throwRootCause(Throwable t) throws Exception
{
t = getRootCause(t);
if (t instanceof Exception) {
throw (Exception) t;
}
throw (Error) t;
}
/**
* Method that will wrap 't' as an {@link IllegalArgumentException} if it
* is a checked exception; otherwise (runtime exception or error) throw as is
*/
public static void throwAsIAE(Throwable t)
{
throwAsIAE(t, t.getMessage());
}
/**
* Method that will wrap 't' as an {@link IllegalArgumentException} (and with
* specified message) if it
* is a checked exception; otherwise (runtime exception or error) throw as is
*/
public static void throwAsIAE(Throwable t, String msg)
{
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
if (t instanceof Error) {
throw (Error) t;
}
throw new IllegalArgumentException(msg, t);
}
/**
* Method that will locate the innermost exception for given Throwable;
* and then wrap it as an {@link IllegalArgumentException} if it
* is a checked exception; otherwise (runtime exception or error) throw as is
*/
public static void unwrapAndThrowAsIAE(Throwable t)
{
throwAsIAE(getRootCause(t));
}
/**
* Method that will locate the innermost exception for given Throwable;
* and then
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> wrap it as an {@link IllegalArgumentException} if it
* is a checked exception; otherwise (runtime exception or error) throw as is
*/
public static void unwrapAndThrowAsIAE(Throwable t, String msg)
{
throwAsIAE(getRootCause(t), msg);
}
/*
/**********************************************************
/* Instantiation
/**********************************************************
*/
/**
* Method that can be called to try to create an instantiate of
* specified type. Instantiation is done using default no-argument
* constructor.
*
* @param canFixAccess Whether it is possible to try to change access
* rights of the default constructor (in case it is not publicly
* accessible) or not.
*
* @throws IllegalArgumentException If instantiation fails for any reason;
* except for cases where constructor throws an unchecked exception
* (which will be passed as is)
*/
public static <T> T createInstance(Class<T> cls, boolean canFixAccess)
throws IllegalArgumentException
{
Constructor<T> ctor = findConstructor(cls, canFixAccess);
if (ctor == null) {
throw new IllegalArgumentException("Class "+cls.getName()+" has no default (no arg) constructor");
}
try {
return ctor.newInstance();
} catch (Exception e) {
ClassUtil.unwrapAndThrowAsIAE(e, "Failed to instantiate class "+cls.getName()+", problem: "+e.getMessage());
return null;
}
}
public static <T> Constructor<T> findConstructor(Class<T> cls, boolean canFixAccess)
throws IllegalArgumentException
{
try {
Constructor<T> ctor = cls.getDeclaredConstructor();
if (canFixAccess) {
checkAndFixAccess(ctor);
} else {
// Has to be public...
if (!Modifier.isPublic(ctor.getModifiers())) {
throw new IllegalArgumentException("Default constructor for "+cls.getName()+" is not accessible (non-public?): not allowed to try modify access via Reflection: can not instantiate type");
}
}
return ctor;
} catch (NoSuchMethodException e) {
;
} catch (Exception e) {
ClassUtil.unwrapAndThrowAsIAE(e, "Failed to find default constructor of class "+cls.getName()+", problem: "+e.getMessage());
}
return null;
}
/*
/**********************************************************
/* Primitive type support
/**********************************************************
*/
/**
* Helper method used to get default value for wrappers used for primitive types
* (0 for Integer etc)
*/
public static Object defaultValue(Class<?> cls)
{
if (cls == Integer.TYPE) {
return Integer.valueOf(0);
}
if (cls == Long.TYPE) {
return Long.
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>valueOf(0L);
}
if (cls == Boolean.TYPE) {
return Boolean.FALSE;
}
if (cls == Double.TYPE) {
return Double.valueOf(0.0);
}
if (cls == Float.TYPE) {
return Float.valueOf(0.0f);
}
if (cls == Byte.TYPE) {
return Byte.valueOf((byte) 0);
}
if (cls == Short.TYPE) {
return Short.valueOf((short) 0);
}
if (cls == Character.TYPE) {
return '\0';
}
throw new IllegalArgumentException("Class "+cls.getName()+" is not a primitive type");
}
/**
* Helper method for finding wrapper type for given primitive type (why isn't
* there one in JDK?)
*/
public static Class<?> wrapperType(Class<?> primitiveType)
{
if (primitiveType == Integer.TYPE) {
return Integer.class;
}
if (primitiveType == Long.TYPE) {
return Long.class;
}
if (primitiveType == Boolean.TYPE) {
return Boolean.class;
}
if (primitiveType == Double.TYPE) {
return Double.class;
}
if (primitiveType == Float.TYPE) {
return Float.class;
}
if (primitiveType == Byte.TYPE) {
return Byte.class;
}
if (primitiveType == Short.TYPE) {
return Short.class;
}
if (primitiveType == Character.TYPE) {
return Character.class;
}
throw new IllegalArgumentException("Class "+primitiveType.getName()+" is not a primitive type");
}
/*
/**********************************************************
/* Access checking/handling methods
/**********************************************************
*/
/**
* Method called to check if we can use the passed method or constructor
* (wrt access restriction -- public methods can be called, others
* usually not); and if not, if there is a work-around for
* the problem.
*/
public static void checkAndFixAccess(Member member)
{
// We know all members are also accessible objects...
AccessibleObject ao = (AccessibleObject) member;
/* 14-Jan-2009, tatu: It seems safe and potentially beneficial to
* always to make it accessible (latter because it will force
* skipping checks we have no use for...), so let's always call it.
*/
//if (!ao.isAccessible()) {
try {
ao.setAccessible(true);
} catch (SecurityException se) {
/* 17-Apr-2009, tatu: Related to [JACKSON-101]: this can fail on
*
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> platforms like EJB and Google App Engine); so let's
* only fail if we really needed it...
*/
if (!ao.isAccessible()) {
Class<?> declClass = member.getDeclaringClass();
throw new IllegalArgumentException("Can not access "+member+" (from class "+declClass.getName()+"; failed to set access: "+se.getMessage());
}
}
//}
}
/*
/**********************************************************
/* Enum type detection
/**********************************************************
*/
/**
* Helper method that can be used to dynamically figure out
* enumeration type of given {@link EnumSet}, without having
* access to its declaration.
* Code is needed to work around design flaw in JDK.
*/
public static Class<? extends Enum<?>> findEnumType(EnumSet<?> s)
{
// First things first: if not empty, easy to determine
if (!s.isEmpty()) {
return findEnumType(s.iterator().next());
}
// Otherwise need to locate using an internal field
return EnumTypeLocator.instance.enumTypeFor(s);
}
/**
* Helper method that can be used to dynamically figure out
* enumeration type of given {@link EnumSet}, without having
* access to its declaration.
* Code is needed to work around design flaw in JDK.
*/
public static Class<? extends Enum<?>> findEnumType(EnumMap<?,?> m)
{
if (!m.isEmpty()) {
return findEnumType(m.keySet().iterator().next());
}
// Otherwise need to locate using an internal field
return EnumTypeLocator.instance.enumTypeFor(m);
}
/**
* Helper method that can be used to dynamically figure out formal
* enumeration type (class) for given enumeration. This is either
* class of enum instance (for "simple" enumerations), or its
* superclass (for enums with instance fields or methods)
*/
@SuppressWarnings("unchecked")
public static Class<? extends Enum<?>> findEnumType(Enum<?> en)
{
// enums with "body" are sub-classes of the formal type
Class<?> ec = en.getClass();
if (ec.getSuperclass() != Enum.class) {
ec = ec.getSuperclass();
}
return (Class<? extends Enum<?>>) ec;
}
/**
* Helper method that can be used to dynamically figure out formal
* enumeration type (class) for given class of an enumeration value.
* This is either class of enum instance (for "simple" enumerations),
* or its superclass (for enums with instance fields or methods)
*/
@SuppressWarnings("unchecked")
public static Class<? extends Enum<?>> findEnumType(Class
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS><?> cls)
{
// enums with "body" are sub-classes of the formal type
if (cls.getSuperclass() != Enum.class) {
cls = cls.getSuperclass();
}
return (Class<? extends Enum<?>>) cls;
}
/*
/**********************************************************
/* Jackson-specific stuff
/**********************************************************
*/
/**
* Method that can be called to determine if given Object is the default
* implementation Jackson uses; as opposed to a custom serializer installed by
* a module or calling application. Determination is done using
* {@link JacksonStdImpl} annotation on handler (serializer, deserializer etc)
* class.
*/
public static boolean isJacksonStdImpl(Object impl) {
return (impl != null) && isJacksonStdImpl(impl.getClass());
}
public static boolean isJacksonStdImpl(Class<?> implClass) {
return (implClass.getAnnotation(JacksonStdImpl.class) != null);
}
public static boolean isBogusClass(Class<?> cls) {
return (cls == Void.class || cls == Void.TYPE
|| cls == com.fasterxml.jackson.databind.annotation.NoClass.class);
}
public static boolean isNonStaticInnerClass(Class<?> cls) {
return (cls.getEnclosingClass() != null)
&& !Modifier.isStatic(cls.getModifiers());
}
/*
/**********************************************************
/* Helper classes
/**********************************************************
*/
/**
* Inner class used to contain gory details of how we can determine
* details of instances of common JDK types like {@link EnumMap}s.
*/
private static class EnumTypeLocator
{
final static EnumTypeLocator instance = new EnumTypeLocator();
private final Field enumSetTypeField;
private final Field enumMapTypeField;
private EnumTypeLocator() {
/* JDK uses following fields to store information about actual Enumeration
* type for EnumSets, EnumMaps...
*/
enumSetTypeField = locateField(EnumSet.class, "elementType", Class.class);
enumMapTypeField = locateField(EnumMap.class, "elementType", Class.class);
}
@SuppressWarnings("unchecked")
public Class<? extends Enum<?>> enumTypeFor(EnumSet<?> set)
{
if (enumSetTypeField != null) {
return (Class<? extends Enum<?>>) get(set, enumSetTypeField);
}
throw new IllegalStateException("Can not figure out type for EnumSet (odd JDK platform?)");
}
@SuppressWarnings("unchecked")
public Class<? extends Enum<?>> enumTypeFor(EnumMap<?,?> set)
{
if (enumMap
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>TypeField != null) {
return (Class<? extends Enum<?>>) get(set, enumMapTypeField);
}
throw new IllegalStateException("Can not figure out type for EnumMap (odd JDK platform?)");
}
private Object get(Object bean, Field field)
{
try {
return field.get(bean);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
private static Field locateField(Class<?> fromClass, String expectedName, Class<?> type)
{
Field found = null;
// First: let's see if we can find exact match:
Field[] fields = fromClass.getDeclaredFields();
for (Field f : fields) {
if (expectedName.equals(f.getName()) && f.getType() == type) {
found = f;
break;
}
}
// And if not, if there is just one field with the type, that field
if (found == null) {
for (Field f : fields) {
if (f.getType() == type) {
// If more than one, can't choose
if (found != null) return null;
found = f;
}
}
}
if (found != null) { // it's non-public, need to force accessible
try {
found.setAccessible(true);
} catch (Throwable t) { }
}
return found;
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.introspect;
import java.lang.annotation.Annotation;
import java.lang.reflect.Member;
import java.util.Collections;
import com.fasterxml.jackson.databind.util.ClassUtil;
/**
* Intermediate base class for annotated entities that are members of
* a class; fields, methods and constructors. This is a superset
* of things that can represent logical properties as it contains
* constructors in addition to fields and methods.
*/
public abstract class AnnotatedMember
extends Annotated
implements java.io.Serializable
{
private static final long serialVersionUID = 1L; // since 2.5
// 19-Dec-2014, tatu: Similarly, assumed NOT to be needed in cases where
// owning object (ObjectMapper or relatives) is being JDK-serialized
/**
* Class that was resolved to produce this member instance; either class that declared
* the member, or one of its subtypes that inherited it.
*
* @since 2.5
*/
protected final transient AnnotatedClass _context;
// Transient since information not needed after construction, so
// no need to persist
protected final transient AnnotationMap _annotations;
/*
@Deprecated // since 2.5
protected AnnotatedMember(AnnotationMap annotations) {
this(null, annotations);
}
*/
protected AnnotatedMember(AnnotatedClass ctxt, AnnotationMap annotations) {
super();
_context = ctxt;
_annotations = annotations;
}
/**
* Copy-constructor.
*
* @since 2.5
*/
protected AnnotatedMember(AnnotatedMember base) {
_context = base._context;
_annotations = base._annotations;
}
/**
* Actual physical class in which this memmber was declared.
* Note that this may be different from what {@link #getContextClass()} returns;
* "owner" may be a sub-type of "declaring class".
*/
public abstract Class<?> getDeclaringClass();
public abstract Member getMember();
/**
* Accessor for {@link AnnotatedClass} that was the type that was resolved
* and that contains this member: this is either the {@link java.lang.Class}
* in which member was declared, or one of its super types. If distinction
* between result type, and actual class in which declaration was found matters,
* you can compare return value to that of {@link #getDeclaringClass()}.
* The main use for this accessor is (usually) to access class annotations.
*<p>
* Also note that owner property is NOT (JDK-)serialized; this should usually not
* matter, but means that while it is accessible during
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.jsontype.impl;
import java.util.*;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.*;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import com.fasterxml.jackson.databind.jsontype.SubtypeResolver;
/**
* Standard {@link SubtypeResolver} implementation.
*/
public class StdSubtypeResolver
extends SubtypeResolver
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
protected LinkedHashSet<NamedType> _registeredSubtypes;
public StdSubtypeResolver() { }
/*
/**********************************************************
/* Public API
/**********************************************************
*/
@Override
public void registerSubtypes(NamedType... types) {
if (_registeredSubtypes == null) {
_registeredSubtypes = new LinkedHashSet<NamedType>();
}
for (NamedType type : types) {
_registeredSubtypes.add(type);
}
}
@Override
public void registerSubtypes(Class<?>... classes) {
NamedType[] types = new NamedType[classes.length];
for (int i = 0, len = classes.length; i < len; ++i) {
types[i] = new NamedType(classes[i]);
}
registerSubtypes(types);
}
/**
*
* @param property Base member to use for type resolution: either annotated type (class),
* or property (field, getter/setter)
*
* @since 2.1
*/
@Override
public Collection<NamedType> collectAndResolveSubtypes(AnnotatedMember property,
MapperConfig<?> config, AnnotationIntrospector ai, JavaType baseType)
{
// for backwards compatibility, must allow null here:
Class<?> rawBase = (baseType == null) ? property.getRawType() : baseType.getRawClass();
HashMap<NamedType, NamedType> collected = new HashMap<NamedType, NamedType>();
// start with registered subtypes (which have precedence)
if (_registeredSubtypes != null) {
for (NamedType subtype : _registeredSubtypes) {
// is it a subtype of root type?
if (rawBase.isAssignableFrom(subtype.getType())) { // yes
AnnotatedClass curr = AnnotatedClass.constructWithoutSuperTypes(subtype.getType(), ai, config);
_collectAndResolve(curr, subtype, config, ai, collected);
}
}
}
// then annotated types for property itself
Collection<NamedType> st =
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> ai.findSubtypes(property);
if (st != null) {
for (NamedType nt : st) {
AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(nt.getType(), ai, config);
_collectAndResolve(ac, nt, config, ai, collected);
}
}
NamedType rootType = new NamedType(rawBase, null);
AnnotatedClass ac = AnnotatedClass.constructWithoutSuperTypes(rawBase, ai, config);
// and finally subtypes via annotations from base type (recursively)
_collectAndResolve(ac, rootType, config, ai, collected);
return new ArrayList<NamedType>(collected.values());
}
@Override
public Collection<NamedType> collectAndResolveSubtypes(AnnotatedClass type,
MapperConfig<?> config, AnnotationIntrospector ai)
{
HashMap<NamedType, NamedType> subtypes = new HashMap<NamedType, NamedType>();
// [JACKSON-257] then consider registered subtypes (which have precedence over annotations)
if (_registeredSubtypes != null) {
Class<?> rawBase = type.getRawType();
for (NamedType subtype : _registeredSubtypes) {
// is it a subtype of root type?
if (rawBase.isAssignableFrom(subtype.getType())) { // yes
AnnotatedClass curr = AnnotatedClass.constructWithoutSuperTypes(subtype.getType(), ai, config);
_collectAndResolve(curr, subtype, config, ai, subtypes);
}
}
}
// and then check subtypes via annotations from base type (recursively)
NamedType rootType = new NamedType(type.getRawType(), null);
_collectAndResolve(type, rootType, config, ai, subtypes);
return new ArrayList<NamedType>(subtypes.values());
}
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
/**
* Method called to find subtypes for a specific type (class)
*/
protected void _collectAndResolve(AnnotatedClass annotatedType, NamedType namedType,
MapperConfig<?> config, AnnotationIntrospector ai,
HashMap<NamedType, NamedType> collectedSubtypes)
{
if (!namedType.hasName()) {
String name = ai.findTypeName(annotatedType);
if (name != null) {
namedType = new NamedType(namedType.getType(), name);
}
}
// First things first: is base type itself included?
if (collectedSubtypes.containsKey(namedType)) {
// if so, no recursion; however, may need to update name?
if (namedType.hasName()) {
NamedType prev = collectedSubtypes.get(namedType);
if (!prev.
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> /* Parser/generator construction
/**********************************************************
*/
protected JsonParser createParserUsingReader(String input)
throws IOException, JsonParseException
{
return createParserUsingReader(new JsonFactory(), input);
}
protected JsonParser createParserUsingReader(JsonFactory f, String input)
throws IOException, JsonParseException
{
return f.createParser(new StringReader(input));
}
protected JsonParser createParserUsingStream(String input, String encoding)
throws IOException, JsonParseException
{
return createParserUsingStream(new JsonFactory(), input, encoding);
}
protected JsonParser createParserUsingStream(JsonFactory f,
String input, String encoding)
throws IOException, JsonParseException
{
/* 23-Apr-2008, tatus: UTF-32 is not supported by JDK, have to
* use our own codec too (which is not optimal since there's
* a chance both encoder and decoder might have bugs, but ones
* that cancel each other out or such)
*/
byte[] data;
if (encoding.equalsIgnoreCase("UTF-32")) {
data = encodeInUTF32BE(input);
} else {
data = input.getBytes(encoding);
}
InputStream is = new ByteArrayInputStream(data);
return f.createParser(is);
}
/*
/**********************************************************
/* Additional assertion methods
/**********************************************************
*/
protected void assertToken(JsonToken expToken, JsonToken actToken)
{
if (actToken != expToken) {
fail("Expected token "+expToken+", current token "+actToken);
}
}
protected void assertToken(JsonToken expToken, JsonParser jp)
{
assertToken(expToken, jp.getCurrentToken());
}
protected void assertType(Object ob, Class<?> expType)
{
if (ob == null) {
fail("Expected an object of type "+expType.getName()+", got null");
}
Class<?> cls = ob.getClass();
if (!expType.isAssignableFrom(cls)) {
fail("Expected type "+expType.getName()+", got "+cls.getName());
}
}
protected void assertValidLocation(JsonLocation location) {
assertNotNull("Should have non-null location", location);
assertTrue("Should have positive line number", location.getLineNr() > 0);
}
protected void verifyException(Throwable e, String... matches)
{
String msg = e.getMessage();
String lmsg = (msg == null) ? "" : msg.toLowerCase();
for (String match : matches) {
String lmatch = match.toLowerCase();
if (lmsg.indexOf(lmatch) >= 0) {
return;
}
}
fail("Expected an
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Set = _generatorSettings.with(schema);
if (genSet == _generatorSettings) {
return this;
}
_verifySchemaType(schema);
return _new(genSet, _prefetch);
}
/**
* @deprecated Since 2.5 use {@link #with(FormatSchema)} instead
*/
@Deprecated
public ObjectWriter withSchema(FormatSchema schema) {
return with(schema);
}
/**
* Method that will construct a new instance that uses specific type
* as the root type for serialization, instead of runtime dynamic
* type of the root object itself.
*<p>
* Note that method does NOT change state of this reader, but
* rather construct and returns a newly configured instance.
*
* @since 2.5
*/
public ObjectWriter forType(JavaType rootType)
{
Prefetch pf;
if (rootType == null || rootType.hasRawClass(Object.class)) {
pf = Prefetch.empty;
} else {
// 15-Mar-2013, tatu: Important! Indicate that static typing is needed:
rootType = rootType.withStaticTyping();
pf = _prefetchRootSerializer(_config, rootType);
}
return (pf == _prefetch) ? this : _new(_generatorSettings, pf);
}
/**
* Method that will construct a new instance that uses specific type
* as the root type for serialization, instead of runtime dynamic
* type of the root object itself.
*
* @since 2.5
*/
public ObjectWriter forType(Class<?> rootType) {
if (rootType == Object.class) {
return forType((JavaType) null);
}
return forType(_config.constructType(rootType));
}
public ObjectWriter forType(TypeReference<?> rootType) {
return forType(_config.getTypeFactory().constructType(rootType.getType()));
}
/**
* @deprecated since 2.5 Use {@link #forType(JavaType)} instead
*/
@Deprecated // since 2.5
public ObjectWriter withType(JavaType rootType) {
return forType(rootType);
}
/**
* @deprecated since 2.5 Use {@link #forType(Class)} instead
*/
@Deprecated // since 2.5
public ObjectWriter withType(Class<?> rootType) {
return forType(rootType);
}
/**
* @deprecated since 2.5 Use {@link #forType(TypeReference)} instead
*/
@Deprecated // since 2.5
public ObjectWriter withType(TypeReference<?> rootType) {
return forType(rootType);
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> /**
* Method that will construct a new instance that uses specified
* serialization view for serialization (with null basically disables
* view processing)
*<p>
* Note that the method does NOT change state of this reader, but
* rather construct and returns a newly configured instance.
*/
public ObjectWriter withView(Class<?> view) {
SerializationConfig newConfig = _config.withView(view);
return (newConfig == _config) ? this : _new(this, newConfig);
}
public ObjectWriter with(Locale l) {
SerializationConfig newConfig = _config.with(l);
return (newConfig == _config) ? this : _new(this, newConfig);
}
public ObjectWriter with(TimeZone tz) {
SerializationConfig newConfig = _config.with(tz);
return (newConfig == _config) ? this : _new(this, newConfig);
}
/**
* Method that will construct a new instance that uses specified default
* {@link Base64Variant} for base64 encoding
*
* @since 2.1
*/
public ObjectWriter with(Base64Variant b64variant) {
SerializationConfig newConfig = _config.with(b64variant);
return (newConfig == _config) ? this : _new(this, newConfig);
}
/**
* @since 2.3
*/
public ObjectWriter with(CharacterEscapes escapes) {
GeneratorSettings genSet = _generatorSettings.with(escapes);
if (genSet == _generatorSettings) {
return this;
}
return _new(genSet, _prefetch);
}
/**
* @since 2.3
*/
public ObjectWriter with(JsonFactory f) {
return (f == _generatorFactory) ? this : _new(this, f);
}
/**
* @since 2.3
*/
public ObjectWriter with(ContextAttributes attrs) {
SerializationConfig newConfig = _config.with(attrs);
return (newConfig == _config) ? this : _new(this, newConfig);
}
/**
* @since 2.3
*/
public ObjectWriter withAttributes(Map<Object,Object> attrs) {
SerializationConfig newConfig = _config.withAttributes(attrs);
return (newConfig == _config) ? this : _new(this, newConfig);
}
/**
* @since 2.3
*/
public ObjectWriter withAttribute(Object key, Object value) {
SerializationConfig newConfig = _config.withAttribute(key, value);
return (newConfig == _config) ? this : _new(this, newConfig);
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> */
@SuppressWarnings("resource")
public byte[] writeValueAsBytes(Object value)
throws JsonProcessingException
{
ByteArrayBuilder bb = new ByteArrayBuilder(_generatorFactory._getBufferRecycler());
try {
_configAndWriteValue(_generatorFactory.createGenerator(bb, JsonEncoding.UTF8), value);
} catch (JsonProcessingException e) { // to support [JACKSON-758]
throw e;
} catch (IOException e) { // shouldn't really happen, but is declared as possibility so:
throw JsonMappingException.fromUnexpectedIOE(e);
}
byte[] result = bb.toByteArray();
bb.release();
return result;
}
/*
/**********************************************************
/* Other public methods
/**********************************************************
*/
/**
* Method for visiting type hierarchy for given type, using specified visitor.
* Visitation uses <code>Serializer</code> hierarchy and related properties
*<p>
* This method can be used for things like
* generating <a href="http://json-schema.org/">Json Schema</a>
* instance for specified type.
*
* @param type Type to generate schema for (possibly with generic signature)
*
* @since 2.2
*/
public void acceptJsonFormatVisitor(JavaType type, JsonFormatVisitorWrapper visitor)
throws JsonMappingException
{
if (type == null) {
throw new IllegalArgumentException("type must be provided");
}
_serializerProvider(_config).acceptJsonFormatVisitor(type, visitor);
}
public boolean canSerialize(Class<?> type) {
return _serializerProvider(_config).hasSerializerFor(type, null);
}
/**
* Method for checking whether instances of given type can be serialized,
* and optionally why (as per {@link Throwable} returned).
*
* @since 2.3
*/
public boolean canSerialize(Class<?> type, AtomicReference<Throwable> cause) {
return _serializerProvider(_config).hasSerializerFor(type, cause);
}
/*
/**********************************************************
/* Overridable helper methods
/**********************************************************
*/
/**
* Overridable helper method used for constructing
* {@link SerializerProvider} to use for serialization.
*/
protected DefaultSerializerProvider _serializerProvider(SerializationConfig config) {
return _serializerProvider.createInstance(config, _serializerFactory);
}
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
/**
* @since 2.2
*/
protected void _verifySchemaType(FormatSchema schema)
{
if (schema != null) {
if (!_generatorFactory.canUseSchema(schema)) {
throw new IllegalArgumentException("Can not use FormatSchema of type "+schema.getClass().getName()
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.lang.reflect.Type;
import java.util.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
/**
* Intermediate base class for Lists, Collections and Arrays
* that contain static (non-dynamic) value types.
*/
@SuppressWarnings("serial")
public abstract class StaticListSerializerBase<T extends Collection<?>>
extends StdSerializer<T>
{
protected StaticListSerializerBase(Class<?> cls) {
super(cls, false);
}
@Deprecated // since 2.5
@Override
public boolean isEmpty(T value) {
return isEmpty(null, value);
}
@Override
public boolean isEmpty(SerializerProvider provider, T value) {
return (value == null) || (value.size() == 0);
}
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint) {
return createSchemaNode("array", true).set("items", contentSchema());
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException {
acceptContentVisitor(visitor.expectArrayFormat(typeHint));
}
/*
/**********************************************************
/* Abstract methods for sub-classes to implement
/**********************************************************
*/
protected abstract JsonNode contentSchema();
protected abstract void acceptContentVisitor(JsonArrayFormatVisitor visitor)
throws JsonMappingException;
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>findObjectReferenceInfo(accessor, objectIdInfo);
Class<?> implClass = objectIdInfo.getGeneratorType();
// Property-based generator is trickier
JavaType idType;
SettableBeanProperty idProp;
ObjectIdGenerator<?> idGen;
ObjectIdResolver resolver = ctxt.objectIdResolverInstance(accessor, objectIdInfo);
if (implClass == ObjectIdGenerators.PropertyGenerator.class) {
PropertyName propName = objectIdInfo.getPropertyName();
idProp = findProperty(propName);
if (idProp == null) {
throw new IllegalArgumentException("Invalid Object Id definition for "
+handledType().getName()+": can not find property with name '"+propName+"'");
}
idType = idProp.getType();
idGen = new PropertyBasedObjectIdGenerator(objectIdInfo.getScope());
} else { // other types need to be simpler
JavaType type = ctxt.constructType(implClass);
idType = ctxt.getTypeFactory().findTypeParameters(type, ObjectIdGenerator.class)[0];
idProp = null;
idGen = ctxt.objectIdGeneratorInstance(accessor, objectIdInfo);
}
JsonDeserializer<?> deser = ctxt.findRootValueDeserializer(idType);
oir = ObjectIdReader.construct(idType, objectIdInfo.getPropertyName(),
idGen, deser, idProp, resolver);
}
}
// either way, need to resolve serializer:
BeanDeserializerBase contextual = this;
if (oir != null && oir != _objectIdReader) {
contextual = contextual.withObjectIdReader(oir);
}
// And possibly add more properties to ignore
if (accessor != null) {
String[] ignorals = intr.findPropertiesToIgnore(accessor);
if (ignorals != null && ignorals.length != 0) {
HashSet<String> newIgnored = ArrayBuilders.setAndArray(contextual._ignorableProps, ignorals);
contextual = contextual.withIgnorableProperties(newIgnored);
}
}
// One more thing: are we asked to serialize POJO as array?
JsonFormat.Shape shape = null;
if (accessor != null) {
JsonFormat.Value format = intr.findFormat((Annotated) accessor);
if (format != null) {
shape = format.getShape();
}
}
if (shape == null) {
shape = _serializationShape;
}
if (shape == JsonFormat.Shape.ARRAY) {
contextual = contextual.asArrayDeserializer();
}
return contextual;
}
/**
* Helper method called to see if given property is part of 'managed' property
* pair (managed + back reference), and if so, handle resolution details
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> will handle gruesome details of dealing with properties
* that have non-static inner class as value...
*/
protected SettableBeanProperty _resolveInnerClassValuedProperty(DeserializationContext ctxt,
SettableBeanProperty prop)
{
/* Should we encounter a property that has non-static inner-class
* as value, we need to add some more magic to find the "hidden" constructor...
*/
JsonDeserializer<Object> deser = prop.getValueDeserializer();
// ideally wouldn't rely on it being BeanDeserializerBase; but for now it'll have to do
if (deser instanceof BeanDeserializerBase) {
BeanDeserializerBase bd = (BeanDeserializerBase) deser;
ValueInstantiator vi = bd.getValueInstantiator();
if (!vi.canCreateUsingDefault()) { // no default constructor
Class<?> valueClass = prop.getType().getRawClass();
Class<?> enclosing = ClassUtil.getOuterClass(valueClass);
// and is inner class of the bean class...
if (enclosing != null && enclosing == _beanType.getRawClass()) {
for (Constructor<?> ctor : valueClass.getConstructors()) {
Class<?>[] paramTypes = ctor.getParameterTypes();
if (paramTypes.length == 1 && paramTypes[0] == enclosing) {
if (ctxt.getConfig().canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(ctor);
}
return new InnerClassProperty(prop, ctor);
}
}
}
}
}
return prop;
}
/*
/**********************************************************
/* Public accessors
/**********************************************************
*/
@Override
public boolean isCachable() { return true; }
@Override
public Class<?> handledType() {
return _beanType.getRawClass();
}
/**
* Overridden to return true for those instances that are
* handling value for which Object Identity handling is enabled
* (either via value type or referring property).
*/
@Override
public ObjectIdReader getObjectIdReader() {
return _objectIdReader;
}
public boolean hasProperty(String propertyName) {
return _beanProperties.find(propertyName) != null;
}
public boolean hasViews() {
return _needViewProcesing;
}
/**
* Accessor for checking number of deserialized properties.
*/
public int getPropertyCount() {
return _beanProperties.size();
}
@Override
public Collection<Object> getKnownPropertyNames() {
ArrayList<Object> names = new ArrayList<Object>();
for (SettableBeanProperty prop : _beanProperties) {
names.add(prop.getName());
}
return names;
}
/**
* @deprecated Since 2.3, use {@link #handledType()} instead
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> */
@Deprecated
public final Class<?> getBeanClass() { return _beanType.getRawClass(); }
@Override
public JavaType getValueType() { return _beanType; }
/**
* Accessor for iterating over properties this deserializer uses; with
* the exception that properties passed via Creator methods
* (specifically, "property-based constructor") are not included,
* but can be accessed separate by calling
* {@link #creatorProperties}
*/
public Iterator<SettableBeanProperty> properties()
{
if (_beanProperties == null) {
throw new IllegalStateException("Can only call after BeanDeserializer has been resolved");
}
return _beanProperties.iterator();
}
/**
* Accessor for finding properties that represents values to pass
* through property-based creator method (constructor or
* factory method)
*
* @since 2.0
*/
public Iterator<SettableBeanProperty> creatorProperties()
{
if (_propertyBasedCreator == null) {
return Collections.<SettableBeanProperty>emptyList().iterator();
}
return _propertyBasedCreator.properties().iterator();
}
public SettableBeanProperty findProperty(PropertyName propertyName)
{
// TODO: start matching full name?
return findProperty(propertyName.getSimpleName());
}
/**
* Accessor for finding the property with given name, if POJO
* has one. Name used is the external name, i.e. name used
* in external data representation (JSON).
*
* @since 2.0
*/
public SettableBeanProperty findProperty(String propertyName)
{
SettableBeanProperty prop = (_beanProperties == null) ?
null : _beanProperties.find(propertyName);
if (prop == null && _propertyBasedCreator != null) {
prop = _propertyBasedCreator.findCreatorProperty(propertyName);
}
return prop;
}
/**
* Alternate find method that tries to locate a property with given
* <code>property index</code>.
* Note that access by index is not necessarily faster than by name,
* since properties are not directly indexable; however, for most
* instances difference is not significant as number of properties
* is low.
*
* @since 2.3
*/
public SettableBeanProperty findProperty(int propertyIndex)
{
SettableBeanProperty prop = (_beanProperties == null) ?
null : _beanProperties.find(propertyIndex);
if (prop == null && _propertyBasedCreator != null) {
prop = _propertyBasedCreator.findCreatorProperty(propertyIndex);
}
return prop;
}
/**
* Method needed by {@link BeanDeserializerFactory} to properly link
* managed- and back-reference pairs.
*/
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import com.fasterxml.jackson.databind.*;
/**
* Container class that contains serializers for JDK types that
* require special handling for some reason.
*/
public class JdkDeserializers
{
private final static HashSet<String> _classNames = new HashSet<String>();
static {
// note: can skip primitive types; other ways to check them:
Class<?>[] types = new Class<?>[] {
UUID.class,
AtomicBoolean.class,
StackTraceElement.class,
ByteBuffer.class
};
for (Class<?> cls : types) { _classNames.add(cls.getName()); }
for (Class<?> cls : FromStringDeserializer.types()) { _classNames.add(cls.getName()); }
}
public static JsonDeserializer<?> find(Class<?> rawType, String clsName)
{
if (_classNames.contains(clsName)) {
JsonDeserializer<?> d = FromStringDeserializer.findDeserializer(rawType);
if (d != null) {
return d;
}
if (rawType == UUID.class) {
return new UUIDDeserializer();
}
if (rawType == StackTraceElement.class) {
return new StackTraceElementDeserializer();
}
if (rawType == AtomicBoolean.class) {
// (note: AtomicInteger/Long work due to single-arg constructor. For now?
return new AtomicBooleanDeserializer();
}
if (rawType == ByteBuffer.class) {
return new ByteBufferDeserializer();
}
}
return null;
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ext;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.Deserializers;
import com.fasterxml.jackson.databind.ser.Serializers;
/**
* Helper class used for isolating details of handling optional+external types
* (javax.xml classes) from standard factories that offer them.
*/
public class OptionalHandlerFactory implements java.io.Serializable
{
private static final long serialVersionUID = 1;
/* 1.6.1+ To make 2 main "optional" handler groups (javax.xml.stream)
* more dynamic, we better only figure out handlers completely dynamically, if and
* when they are needed. To do this we need to assume package prefixes.
*/
private final static String PACKAGE_PREFIX_JAVAX_XML = "javax.xml.";
private final static String SERIALIZERS_FOR_JAVAX_XML = "com.fasterxml.jackson.databind.ext.CoreXMLSerializers";
private final static String DESERIALIZERS_FOR_JAVAX_XML = "com.fasterxml.jackson.databind.ext.CoreXMLDeserializers";
// Plus we also have a single serializer for DOM Node:
private final static String CLASS_NAME_DOM_NODE = "org.w3c.dom.Node";
private final static String CLASS_NAME_DOM_DOCUMENT = "org.w3c.dom.Node";
private final static String SERIALIZER_FOR_DOM_NODE = "com.fasterxml.jackson.databind.ext.DOMSerializer";
private final static String DESERIALIZER_FOR_DOM_DOCUMENT = "com.fasterxml.jackson.databind.ext.DOMDeserializer$DocumentDeserializer";
private final static String DESERIALIZER_FOR_DOM_NODE = "com.fasterxml.jackson.databind.ext.DOMDeserializer$NodeDeserializer";
public final static OptionalHandlerFactory instance = new OptionalHandlerFactory();
protected OptionalHandlerFactory() { }
/*
/**********************************************************
/* Public API
/**********************************************************
*/
public JsonSerializer<?> findSerializer(SerializationConfig config, JavaType type,
BeanDescription beanDesc)
{
Class<?> rawType = type.getRawClass();
String className = rawType.getName();
String factoryName;
if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML)
|| hasSupertypeStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) {
factoryName = SERIALIZERS_FOR_JAVAX_XML;
} else if (doesImplement(rawType, CLASS_NAME_DOM_NODE)) {
return (JsonSerializer<?>) instantiate(SERIALIZER_FOR_DOM_NODE);
} else {
return null;
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
}
Object ob = instantiate(factoryName);
if (ob == null) { // could warn, if we had logging system (j.u.l?)
return null;
}
return ((Serializers) ob).findSerializer(config, type, beanDesc);
}
public JsonDeserializer<?> findDeserializer(JavaType type, DeserializationConfig config,
BeanDescription beanDesc)
throws JsonMappingException
{
Class<?> rawType = type.getRawClass();
String className = rawType.getName();
String factoryName;
if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML)
|| hasSupertypeStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) {
factoryName = DESERIALIZERS_FOR_JAVAX_XML;
} else if (doesImplement(rawType, CLASS_NAME_DOM_DOCUMENT)) {
return (JsonDeserializer<?>) instantiate(DESERIALIZER_FOR_DOM_DOCUMENT);
} else if (doesImplement(rawType, CLASS_NAME_DOM_NODE)) {
return (JsonDeserializer<?>) instantiate(DESERIALIZER_FOR_DOM_NODE);
} else {
return null;
}
Object ob = instantiate(factoryName);
if (ob == null) { // could warn, if we had logging system (j.u.l?)
return null;
}
return ((Deserializers) ob).findBeanDeserializer(type, config, beanDesc);
}
/*
/**********************************************************
/* Internal helper methods
/**********************************************************
*/
private Object instantiate(String className)
{
try {
return Class.forName(className).newInstance();
} catch (LinkageError e) { }
// too many different kinds to enumerate here:
catch (Exception e) { }
return null;
}
private boolean doesImplement(Class<?> actualType, String classNameToImplement)
{
for (Class<?> type = actualType; type != null; type = type.getSuperclass()) {
if (type.getName().equals(classNameToImplement)) {
return true;
}
// or maybe one of super-interfaces
if (hasInterface(type, classNameToImplement)) {
return true;
}
}
return false;
}
private boolean hasInterface(Class<?> type, String interfaceToImplement)
{
Class<?>[] interfaces = type.getInterfaces();
for (Class<?> iface : interfaces) {
if (iface.getName().equals(interfaceToImplement)) {
return true;
}
}
// maybe super-interface?
for (Class<?> iface : interfaces) {
if (hasInterface(iface, interfaceToImplement)) {
return true;
}
}
return false;
}
private boolean has
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>SupertypeStartingWith(Class<?> rawType, String prefix)
{
// first, superclasses
for (Class<?> supertype = rawType.getSuperclass(); supertype != null; supertype = supertype.getSuperclass()) {
if (supertype.getName().startsWith(prefix)) {
return true;
}
}
// then interfaces
for (Class<?> cls = rawType; cls != null; cls = cls.getSuperclass()) {
if (hasInterfaceStartingWith(cls, prefix)) {
return true;
}
}
return false;
}
private boolean hasInterfaceStartingWith(Class<?> type, String prefix)
{
Class<?>[] interfaces = type.getInterfaces();
for (Class<?> iface : interfaces) {
if (iface.getName().startsWith(prefix)) {
return true;
}
}
// maybe super-interface?
for (Class<?> iface : interfaces) {
if (hasInterfaceStartingWith(iface, prefix)) {
return true;
}
}
return false;
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> active serialization, if any.
* Only set for non-blueprint instances.
*/
final protected Class<?> _serializationView;
/*
/**********************************************************
/* Configuration, factories
/**********************************************************
*/
/**
* Factory used for constructing actual serializer instances.
* Only set for non-blueprint instances.
*/
final protected SerializerFactory _serializerFactory;
/*
/**********************************************************
/* Helper objects for caching, reuse
/**********************************************************
*/
/**
* Cache for doing type-to-value-serializer lookups.
*/
final protected SerializerCache _serializerCache;
/**
* Helper object for keeping track of introspected root names
*/
final protected RootNameLookup _rootNames;
/**
* Lazily-constructed holder for per-call attributes.
* Only set for non-blueprint instances.
*
* @since 2.3
*/
protected transient ContextAttributes _attributes;
/*
/**********************************************************
/* Configuration, specialized serializers
/**********************************************************
*/
/**
* Serializer that gets called for values of types for which no
* serializers can be constructed.
*<p>
* The default serializer will simply thrown an exception.
*/
protected JsonSerializer<Object> _unknownTypeSerializer = DEFAULT_UNKNOWN_SERIALIZER;
/**
* Serializer used to output non-null keys of Maps (which will get
* output as JSON Objects), if not null; if null, us the standard
* default key serializer.
*/
protected JsonSerializer<Object> _keySerializer;
/**
* Serializer used to output a null value. Default implementation
* writes nulls using {@link JsonGenerator#writeNull}.
*/
protected JsonSerializer<Object> _nullValueSerializer = NullSerializer.instance;
/**
* Serializer used to (try to) output a null key, due to an entry of
* {@link java.util.Map} having null key.
* The default implementation will throw an exception if this happens;
* alternative implementation (like one that would write an Empty String)
* can be defined.
*/
protected JsonSerializer<Object> _nullKeySerializer = DEFAULT_NULL_KEY_SERIALIZER;
/*
/**********************************************************
/* State, for non-blueprint instances: generic
/**********************************************************
*/
/**
* For fast lookups, we will have a local non-shared read-only
* map that contains serializers previously fetched.
*/
protected final ReadOnlyClassToSerializerMap _knownSerializers;
/**
* Lazily acquired and instantiated formatter object: initialized
* first time it is needed, reused afterwards. Used via instances
* (not blueprints), so that access need not be thread-safe.
*/
protected DateFormat _dateFormat;
/**
* Flag set to indicate that we are using vanilla null value
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> Method that can be used to specify serializer that will be
* used to write JSON property names matching null keys for Java
* Maps (which will throw an exception if try write such property
* name)
*/
public void setDefaultKeySerializer(JsonSerializer<Object> ks)
{
if (ks == null) {
throw new IllegalArgumentException("Can not pass null JsonSerializer");
}
_keySerializer = ks;
}
/**
* Method that can be used to specify serializer that will be
* used to write JSON values matching Java null values
* instead of default one (which simply writes JSON null).
*<p>
* Note that you can get finer control over serializer to use by overriding
* {@link #findNullValueSerializer}, which gets called once per each
* property.
*/
public void setNullValueSerializer(JsonSerializer<Object> nvs)
{
if (nvs == null) {
throw new IllegalArgumentException("Can not pass null JsonSerializer");
}
_nullValueSerializer = nvs;
}
/**
* Method that can be used to specify serializer to use for serializing
* all non-null JSON property names, unless more specific key serializer
* is found (i.e. if not custom key serializer has been registered for
* Java type).
*<p>
* Note that key serializer registration are different from value serializer
* registrations.
*/
public void setNullKeySerializer(JsonSerializer<Object> nks)
{
if (nks == null) {
throw new IllegalArgumentException("Can not pass null JsonSerializer");
}
_nullKeySerializer = nks;
}
/*
/**********************************************************
/* DatabindContext implementation
/**********************************************************
*/
/**
* Method for accessing configuration for the serialization processing.
*/
@Override
public final SerializationConfig getConfig() { return _config; }
@Override
public final AnnotationIntrospector getAnnotationIntrospector() {
return _config.getAnnotationIntrospector();
}
@Override
public final TypeFactory getTypeFactory() {
return _config.getTypeFactory();
}
@Override
public final Class<?> getActiveView() { return _serializationView; }
/**
* @deprecated Since 2.2, use {@link #getActiveView} instead.
*/
@Deprecated
public final Class<?> getSerializationView() { return _serializationView; }
/*
/**********************************************************
/* Generic attributes (2.3+)
/**********************************************************
*/
@Override
public Object getAttribute(Object key) {
return _attributes.getAttribute(key);
}
@Override
public SerializerProvider setAttribute(Object key, Object value)
{
_attributes = _attributes.withPerCallAttribute(key, value);
return this;
}
/*
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> are fatal problems with
* accessing suitable serializer; including that of not
* finding any serializer
*/
@SuppressWarnings("unchecked")
public JsonSerializer<Object> findValueSerializer(Class<?> valueType, BeanProperty property)
throws JsonMappingException
{
// Fast lookup from local lookup thingy works?
JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType);
if (ser == null) {
// If not, maybe shared map already has it?
ser = _serializerCache.untypedValueSerializer(valueType);
if (ser == null) {
// ... possibly as fully typed?
ser = _serializerCache.untypedValueSerializer(_config.constructType(valueType));
if (ser == null) {
// If neither, must create
ser = _createAndCacheUntypedSerializer(valueType);
// Not found? Must use the unknown type serializer, which will report error later on
if (ser == null) {
ser = getUnknownTypeSerializer(valueType);
// Should this be added to lookups?
if (CACHE_UNKNOWN_MAPPINGS) {
_serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this);
}
return ser;
}
}
}
}
// at this point, resolution has occured, but not contextualization
return (JsonSerializer<Object>) handleSecondaryContextualization(ser, property);
}
/**
* Similar to {@link #findValueSerializer(Class,BeanProperty)}, but takes
* full generics-aware type instead of raw class.
* This is necessary for accurate handling of external type information,
* to handle polymorphic types.
*
* @param property When creating secondary serializers, property for which
* serializer is needed: annotations of the property (or bean that contains it)
* may be checked to create contextual serializers.
*/
@SuppressWarnings("unchecked")
public JsonSerializer<Object> findValueSerializer(JavaType valueType, BeanProperty property)
throws JsonMappingException
{
// (see comments from above method)
JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType);
if (ser == null) {
ser = _serializerCache.untypedValueSerializer(valueType);
if (ser == null) {
ser = _createAndCacheUntypedSerializer(valueType);
if (ser == null) {
ser = getUnknownTypeSerializer(valueType.getRawClass());
if (CACHE_UNKNOWN_MAPPINGS) {
_serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this);
}
return ser;
}
}
}
return (JsonSerializer<Object>) handleSecondaryContextualization(ser, property);
}
/**
* Method variant used when we
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> do NOT want contextualization to happen; it will need
* to be handled at a later point, but caller wants to be able to do that
* as needed; sometimes to avoid infinite loops
*
* @since 2.5
*/
public JsonSerializer<Object> findValueSerializer(Class<?> valueType) throws JsonMappingException
{
// (see comments from above method)
JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType);
if (ser == null) {
ser = _serializerCache.untypedValueSerializer(valueType);
if (ser == null) {
ser = _serializerCache.untypedValueSerializer(_config.constructType(valueType));
if (ser == null) {
ser = _createAndCacheUntypedSerializer(valueType);
if (ser == null) {
ser = getUnknownTypeSerializer(valueType);
if (CACHE_UNKNOWN_MAPPINGS) {
_serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this);
}
}
}
}
}
return ser;
}
/**
* Method variant used when we do NOT want contextualization to happen; it will need
* to be handled at a later point, but caller wants to be able to do that
* as needed; sometimes to avoid infinite loops
*
* @since 2.5
*/
public JsonSerializer<Object> findValueSerializer(JavaType valueType)
throws JsonMappingException
{
// (see comments from above method)
JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType);
if (ser == null) {
ser = _serializerCache.untypedValueSerializer(valueType);
if (ser == null) {
ser = _createAndCacheUntypedSerializer(valueType);
if (ser == null) {
ser = getUnknownTypeSerializer(valueType.getRawClass());
if (CACHE_UNKNOWN_MAPPINGS) {
_serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this);
}
}
}
}
return ser;
}
/**
* Similar to {@link #findValueSerializer(JavaType, BeanProperty)}, but used
* when finding "primary" property value serializer (one directly handling
* value of the property). Difference has to do with contextual resolution,
* and method(s) called: this method should only be called when caller is
* certain that this is the primary property value serializer.
*
* @param property Property that is being handled; will never be null, and its
* type has to match <code>valueType</code> parameter.
*
* @since 2.3
*/
@SuppressWarnings("unchecked")
public JsonSerializer<Object> findPrimaryPropertySerializer(
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>JavaType valueType, BeanProperty property)
throws JsonMappingException
{
JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType);
if (ser == null) {
ser = _serializerCache.untypedValueSerializer(valueType);
if (ser == null) {
ser = _createAndCacheUntypedSerializer(valueType);
if (ser == null) {
ser = getUnknownTypeSerializer(valueType.getRawClass());
// Should this be added to lookups?
if (CACHE_UNKNOWN_MAPPINGS) {
_serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this);
}
return ser;
}
}
}
return (JsonSerializer<Object>) handlePrimaryContextualization(ser, property);
}
/**
* @since 2.3
*/
@SuppressWarnings("unchecked")
public JsonSerializer<Object> findPrimaryPropertySerializer(Class<?> valueType,
BeanProperty property)
throws JsonMappingException
{
JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType);
if (ser == null) {
ser = _serializerCache.untypedValueSerializer(valueType);
if (ser == null) {
ser = _serializerCache.untypedValueSerializer(_config.constructType(valueType));
if (ser == null) {
ser = _createAndCacheUntypedSerializer(valueType);
if (ser == null) {
ser = getUnknownTypeSerializer(valueType);
if (CACHE_UNKNOWN_MAPPINGS) {
_serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this);
}
return ser;
}
}
}
}
return (JsonSerializer<Object>) handlePrimaryContextualization(ser, property);
}
/**
* Method called to locate regular serializer, matching type serializer,
* and if both found, wrap them in a serializer that calls both in correct
* sequence. This method is currently only used for root-level serializer
* handling to allow for simpler caching. A call can always be replaced
* by equivalent calls to access serializer and type serializer separately.
*
* @param valueType Type for purpose of locating a serializer; usually dynamic
* runtime type, but can also be static declared type, depending on configuration
* @param cache Whether resulting value serializer should be cached or not; this is just
* a hint
* @param property When creating secondary serializers, property for which
* serializer is needed: annotations of the property (or bean that contains it)
* may be checked to create contextual serializers.
*/
public JsonSerializer<Object> findTypedValueSerializer(Class<?> valueType,
boolean cache, BeanProperty property)
throws JsonMappingException
{
// Two-phase
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> Method called to get the serializer to use if provider
* can not determine an actual type-specific serializer
* to use; typically when none of {@link SerializerFactory}
* instances are able to construct a serializer.
*<p>
* Typically, returned serializer will throw an exception,
* although alternatively {@link com.fasterxml.jackson.databind.ser.std.ToStringSerializer}
* could be returned as well.
*
* @param unknownType Type for which no serializer is found
*/
public JsonSerializer<Object> getUnknownTypeSerializer(Class<?> unknownType) {
return _unknownTypeSerializer;
}
/**
* Helper method called to see if given serializer is considered to be
* something returned by {@link #getUnknownTypeSerializer}, that is, something
* for which no regular serializer was found or constructed.
*
* @since 2.5
*/
public boolean isUnknownTypeSerializer(JsonSerializer<?> ser) {
return (ser == _unknownTypeSerializer) || (ser == null);
}
/*
/**********************************************************
/* Methods for creating instances based on annotations
/**********************************************************
*/
/**
* Method that can be called to construct and configure serializer instance,
* either given a {@link Class} to instantiate (with default constructor),
* or an uninitialized serializer instance.
* Either way, serialize will be properly resolved
* (via {@link com.fasterxml.jackson.databind.ser.ResolvableSerializer}) and/or contextualized
* (via {@link com.fasterxml.jackson.databind.ser.ContextualSerializer}) as necessary.
*
* @param annotated Annotated entity that contained definition
* @param serDef Serializer definition: either an instance or class
*/
public abstract JsonSerializer<Object> serializerInstance(Annotated annotated,
Object serDef)
throws JsonMappingException;
/*
/**********************************************************
/* Support for contextualization
/**********************************************************
*/
/**
* Method called for primary property serializers (ones
* directly created to serialize values of a POJO property),
* to handle details of resolving
* {@link ContextualSerializer} with given property context.
*
* @param property Property for which the given primary serializer is used; never null.
*
* @since 2.3
*/
public JsonSerializer<?> handlePrimaryContextualization(JsonSerializer<?> ser,
BeanProperty property)
throws JsonMappingException
{
if (ser != null) {
if (ser instanceof ContextualSerializer) {
ser = ((ContextualSerializer) ser).createContextual(this, property);
}
}
return ser;
}
/**
* Method called for secondary property serializers (ones
* NOT directly created to serialize values of a POJO property
* but instead created as a dependant serializer
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> -- such as value serializers
* for structured types, or serializers for root values)
* to handle details of resolving
* {@link ContextualDeserializer} with given property context.
* Given that these serializers are not directly related to given property
* (or, in case of root value property, to any property), annotations
* accessible may or may not be relevant.
*
* @param property Property for which serializer is used, if any; null
* when deserializing root values
*
* @since 2.3
*/
public JsonSerializer<?> handleSecondaryContextualization(JsonSerializer<?> ser,
BeanProperty property)
throws JsonMappingException
{
if (ser != null) {
if (ser instanceof ContextualSerializer) {
ser = ((ContextualSerializer) ser).createContextual(this, property);
}
}
return ser;
}
/*
/********************************************************
/* Convenience methods for serializing using default methods
/********************************************************
*/
/**
* Convenience method that will serialize given value (which can be
* null) using standard serializer locating functionality. It can
* be called for all values including field and Map values, but usually
* field values are best handled calling
* {@link #defaultSerializeField} instead.
*/
public final void defaultSerializeValue(Object value, JsonGenerator jgen) throws IOException
{
if (value == null) {
if (_stdNullValueSerializer) { // minor perf optimization
jgen.writeNull();
} else {
_nullValueSerializer.serialize(null, jgen, this);
}
} else {
Class<?> cls = value.getClass();
findTypedValueSerializer(cls, true, null).serialize(value, jgen, this);
}
}
/**
* Convenience method that will serialize given field with specified
* value. Value may be null. Serializer is done using the usual
* null) using standard serializer locating functionality.
*/
public final void defaultSerializeField(String fieldName, Object value, JsonGenerator jgen)
throws IOException
{
jgen.writeFieldName(fieldName);
if (value == null) {
/* Note: can't easily check for suppression at this point
* any more; caller must check it.
*/
if (_stdNullValueSerializer) { // minor perf optimization
jgen.writeNull();
} else {
_nullValueSerializer.serialize(null, jgen, this);
}
} else {
Class<?> cls = value.getClass();
findTypedValueSerializer(cls, true, null).serialize(value, jgen, this);
}
}
/**
* Method that will handle serialization of Date(-like) values, using
* {@link SerializationConfig} settings to determine expected serialization
* behavior.
* Note: date here
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> {
_nullValueSerializer.serialize(null, jgen, this);
}
}
/*
/********************************************************
/* Error reporting
/********************************************************
*/
/**
* @since 2.6
*/
public JsonMappingException mappingException(String message, Object... args) {
if (args != null && args.length > 0) {
message = String.format(message, args);
}
return new JsonMappingException(message);
}
/*
/********************************************************
/* Helper methods
/********************************************************
*/
protected void _reportIncompatibleRootType(Object value, JavaType rootType)
throws IOException, JsonProcessingException
{
/* 07-Jan-2010, tatu: As per [JACKSON-456] better handle distinction between wrapper types,
* primitives
*/
if (rootType.isPrimitive()) {
Class<?> wrapperType = ClassUtil.wrapperType(rootType.getRawClass());
// If it's just difference between wrapper, primitive, let it slide
if (wrapperType.isAssignableFrom(value.getClass())) {
return;
}
}
throw new JsonMappingException("Incompatible types: declared root type ("+rootType+") vs "
+value.getClass().getName());
}
/**
* Method that will try to find a serializer, either from cache
* or by constructing one; but will not return an "unknown" serializer
* if this can not be done but rather returns null.
*
* @return Serializer if one can be found, null if not.
*/
protected JsonSerializer<Object> _findExplicitUntypedSerializer(Class<?> runtimeType)
throws JsonMappingException
{
// Fast lookup from local lookup thingy works?
JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(runtimeType);
if (ser == null) {
// If not, maybe shared map already has it?
ser = _serializerCache.untypedValueSerializer(runtimeType);
if (ser == null) {
ser = _createAndCacheUntypedSerializer(runtimeType);
}
}
/* 18-Sep-2014, tatu: This is unfortunate patch over related change
* that pushes creation of "unknown type" serializer deeper down
* in BeanSerializerFactory; as a result, we need to "undo" creation
* here.
*/
if (isUnknownTypeSerializer(ser)) {
return null;
}
return ser;
}
/*
/**********************************************************
/* Low-level methods for actually constructing and initializing
/* serializers
/**********************************************************
*/
/**
* Method that will try to construct a value serializer; and if
* one is successfully created, cache it for reuse.
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
*/
protected JsonSerializer<Object> _createAndCacheUntypedSerializer(Class<?> type)
throws JsonMappingException
{
JsonSerializer<Object> ser;
try {
ser = _createUntypedSerializer(_config.constructType(type));
} catch (IllegalArgumentException iae) {
/* We better only expose checked exceptions, since those
* are what caller is expected to handle
*/
throw new JsonMappingException(iae.getMessage(), null, iae);
}
if (ser != null) {
_serializerCache.addAndResolveNonTypedSerializer(type, ser, this);
}
return ser;
}
protected JsonSerializer<Object> _createAndCacheUntypedSerializer(JavaType type)
throws JsonMappingException
{
JsonSerializer<Object> ser;
try {
ser = _createUntypedSerializer(type);
} catch (IllegalArgumentException iae) {
/* We better only expose checked exceptions, since those
* are what caller is expected to handle
*/
throw new JsonMappingException(iae.getMessage(), null, iae);
}
if (ser != null) {
_serializerCache.addAndResolveNonTypedSerializer(type, ser, this);
}
return ser;
}
/**
* @since 2.1
*/
protected JsonSerializer<Object> _createUntypedSerializer(JavaType type)
throws JsonMappingException
{
// 17-Feb-2013, tatu: Used to call deprecated method (that passed property)
return (JsonSerializer<Object>)_serializerFactory.createSerializer(this, type);
}
/**
* Helper method called to resolve and contextualize given
* serializer, if and as necessary.
*/
@SuppressWarnings("unchecked")
protected JsonSerializer<Object> _handleContextualResolvable(JsonSerializer<?> ser,
BeanProperty property)
throws JsonMappingException
{
if (ser instanceof ResolvableSerializer) {
((ResolvableSerializer) ser).resolve(this);
}
return (JsonSerializer<Object>) handleSecondaryContextualization(ser, property);
}
@SuppressWarnings("unchecked")
protected JsonSerializer<Object> _handleResolvable(JsonSerializer<?> ser)
throws JsonMappingException
{
if (ser instanceof ResolvableSerializer) {
((ResolvableSerializer) ser).resolve(this);
}
return (JsonSerializer<Object>) ser;
}
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
protected final DateFormat _dateFormat()
{
if (_dateFormat != null) {
return _dateFormat;
}
/* 24-Feb-2012, tatu: At this point, all timezone configuration
* should have occured, with respect to default dateformat
*
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.type;
import com.fasterxml.jackson.databind.JavaType;
/**
* Type that represents Java Collection types (Lists, Sets).
*/
public final class CollectionType
extends CollectionLikeType
{
private static final long serialVersionUID = -7834910259750909424L;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
private CollectionType(Class<?> collT, JavaType elemT,
Object valueHandler, Object typeHandler, boolean asStatic)
{
super(collT, elemT, valueHandler, typeHandler, asStatic);
}
@Override
protected JavaType _narrow(Class<?> subclass) {
return new CollectionType(subclass, _elementType, null, null, _asStatic);
}
@Override
public JavaType narrowContentsBy(Class<?> contentClass)
{
// Can do a quick check first:
if (contentClass == _elementType.getRawClass()) {
return this;
}
return new CollectionType(_class, _elementType.narrowBy(contentClass),
_valueHandler, _typeHandler, _asStatic);
}
@Override
public JavaType widenContentsBy(Class<?> contentClass)
{
// Can do a quick check first:
if (contentClass == _elementType.getRawClass()) {
return this;
}
return new CollectionType(_class, _elementType.widenBy(contentClass),
_valueHandler, _typeHandler, _asStatic);
}
public static CollectionType construct(Class<?> rawType, JavaType elemT)
{
// nominally component types will be just Object.class
return new CollectionType(rawType, elemT, null, null, false);
}
// Since 1.7:
@Override
public CollectionType withTypeHandler(Object h) {
return new CollectionType(_class, _elementType, _valueHandler, h, _asStatic);
}
// Since 1.7:
@Override
public CollectionType withContentTypeHandler(Object h)
{
return new CollectionType(_class, _elementType.withTypeHandler(h),
_valueHandler, _typeHandler, _asStatic);
}
@Override
public CollectionType withValueHandler(Object h) {
return new CollectionType(_class, _elementType, h, _typeHandler, _asStatic);
}
@Override
public CollectionType withContentValueHandler(Object h) {
return new CollectionType(_class, _elementType.withValueHandler(h),
_valueHandler, _typeHandler, _asStatic);
}
@Override
public CollectionType withStaticTyping() {
if (_
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>asStatic) {
return this;
}
return new CollectionType(_class, _elementType.withStaticTyping(),
_valueHandler, _typeHandler, true);
}
/*
/**********************************************************
/* Overridden accessors
/**********************************************************
*/
@Override
public Class<?> getParameterSource() {
return java.util.Collection.class;
}
/*
/**********************************************************
/* Standard methods
/**********************************************************
*/
@Override
public String toString()
{
return "[collection type; class "+_class.getName()+", contains "+_elementType+"]";
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.util.Converter;
/**
* Annotation used for configuring serialization aspects, by attaching
* to "getter" methods or fields, or to value classes.
* When annotating value classes, configuration is used for instances
* of the value class but can be overridden by more specific annotations
* (ones that attach to methods or fields).
*<p>
* An example annotation would be:
*<pre>
* @JsonSerialize(using=MySerializer.class,
* as=MySubClass.class,
* typing=JsonSerialize.Typing.STATIC
* )
*</pre>
* (which would be redundant, since some properties block others:
* specifically, 'using' has precedence over 'as', which has precedence
* over 'typing' setting)
*/
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@com.fasterxml.jackson.annotation.JacksonAnnotation
public @interface JsonSerialize
{
// // // Annotations for explicitly specifying deserializer
/**
* Serializer class to use for
* serializing associated value. Depending on what is annotated,
* value is either an instance of annotated class (used globablly
* anywhere where class serializer is needed); or only used for
* serializing property access via a getter method.
*/
public Class<? extends JsonSerializer<?>> using() default JsonSerializer.None.class;
/**
* Serializer class to use for serializing contents (elements
* of a Collection/array, values of Maps) of annotated property.
* Can only be used on properties (methods, fields, constructors),
* and not value classes themselves (as they are typically generic)
*/
public Class<? extends JsonSerializer<?>> contentUsing()
default JsonSerializer.None.class;
/**
* Serializer class to use for serializing Map keys
* of annotated property.
* Can only be used on properties (methods, fields, constructors),
* and not value classes themselves.
*/
public Class<? extends JsonSerializer<?>> keyUsing()
default JsonSerializer.None.class;
/**
* Serializer class to use for serializing nulls for properties that
* are annotated, instead of the
* default null serializer.
* Note that using this property when annotation types (classes) has
* no effect currently (it is possible this could be improved in future).
*
*
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> @since 2.3
*/
public Class<? extends JsonSerializer<?>> nullsUsing()
default JsonSerializer.None.class;
// // // Annotations for type handling, explicit declaration
// // // (type used for choosing deserializer, if not explicitly
// // // specified)
/**
* Supertype (of declared type, which itself is supertype of runtime type)
* to use as type when locating serializer to use.
*<p>
* Bogus type {@link Void} can be used to indicate that declared
* type is used as is (i.e. this annotation property has no setting);
* this since annotation properties are not allowed to have null value.
*<p>
* Note: if {@link #using} is also used it has precedence
* (since it directly specifies
* serializer, whereas this would only be used to locate the
* serializer)
* and value of this annotation property is ignored.
*/
public Class<?> as() default Void.class;
/**
* Concrete type to serialize keys of {@link java.util.Map} as,
* instead of type otherwise declared.
* Must be a supertype of declared type; otherwise an exception may be
* thrown by serializer.
*/
public Class<?> keyAs() default Void.class;
/**
* Concrete type to serialize content value (elements
* of a Collection/array, values of Maps) as,
* instead of type otherwise declared.
* Must be a supertype of declared type; otherwise an exception may be
* thrown by serializer.
*/
public Class<?> contentAs() default Void.class;
/**
* Whether type detection used is dynamic or static: that is,
* whether actual runtime type is used (dynamic), or just the
* declared type (static).
*<p>
* Note that Jackson 2.3 changed default to <code>DEFAULT_TYPING</code>,
* which is roughly same as saying "whatever".
* This is important as it allows avoiding accidental overrides
* at property level.
*/
public Typing typing() default Typing.DEFAULT_TYPING;
// // // Annotations for specifying intermediate Converters (2.2+)
/**
* Which helper object is to be used to convert type into something
* that Jackson knows how to serialize; either because base type
* can not be serialized easily, or just to alter serialization.
*
* @since 2.2
*/
public Class<? extends Converter<?,?>> converter() default Converter.None.class;
/**
* Similar to {@link #converter}, but used for values of structures types
* (List, arrays, Maps).
* Note that this property does NOT have effect when used as Class annotation;
* it can
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> only be used as property annotation: this because association between
* container and value types is loose and as such converters seldom make sense
* for such usage.
*
* @since 2.2
*/
public Class<? extends Converter<?,?>> contentConverter() default Converter.None.class;
// // // Annotation(s) for inclusion criteria
/**
* Which properties of annotated Bean are
* to be included in serialization (has no effect on other types
* like enums, primitives or collections).
* Choices are "all", "properties that have value other than null"
* and "properties that have non-default value" (i.e. default value
* being property setting for a Bean constructed with default no-arg
* constructor, often null).
*<p>
* Note that Jackson 2.3 changed default to <code>DEFAULT_INCLUSION</code>,
* which is roughly same as saying "whatever". This is important because
* it allows hierarchic default values to be used.
*
* @deprecated As of Jackson 2.0, this annotation has been replaced
* by {@link com.fasterxml.jackson.annotation.JsonInclude}
*/
@Deprecated
public Inclusion include() default Inclusion.DEFAULT_INCLUSION;
/*
/**********************************************************
/* Value enumerations needed
/**********************************************************
*/
/**
* Enumeration used with {@link JsonSerialize#include} property
* to define which properties
* of Java Beans are to be included in serialization
*/
public enum Inclusion
{
/**
* Value that indicates that properties are to be always included,
* independent of value
*/
ALWAYS,
/**
* Value that indicates that only properties with non-null
* values are to be included.
*/
NON_NULL,
/**
* Value that indicates that only properties that have values
* that differ from default settings (meaning values they have
* when Bean is constructed with its no-arguments constructor)
* are to be included. Value is generally not useful with
* {@link java.util.Map}s, since they have no default values;
* and if used, works same as {@link #ALWAYS}.
*/
NON_DEFAULT,
/**
* Value that indicates that only properties that have values
* that values that are null or what is considered empty are
* not to be included.
* Emptiness is defined for following type:
*<ul>
* <li>For {@link java.util.Collection}s and {@link java.util.Map}s,
* method <code>isEmpty()</code> is called;
* </li>
* <li>For Java arrays, empty arrays are ones with length of
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> with slightly
* different settings. When sub-classing, MUST be overridden.
*/
@SuppressWarnings("unchecked")
protected MapDeserializer withResolved(KeyDeserializer keyDeser,
TypeDeserializer valueTypeDeser, JsonDeserializer<?> valueDeser,
HashSet<String> ignorable)
{
if ((_keyDeserializer == keyDeser) && (_valueDeserializer == valueDeser)
&& (_valueTypeDeserializer == valueTypeDeser) && (_ignorableProperties == ignorable)) {
return this;
}
return new MapDeserializer(this,
keyDeser, (JsonDeserializer<Object>) valueDeser, valueTypeDeser, ignorable);
}
/**
* Helper method used to check whether we can just use the default key
* deserialization, where JSON String becomes Java String.
*/
protected final boolean _isStdKeyDeser(JavaType mapType, KeyDeserializer keyDeser)
{
if (keyDeser == null) {
return true;
}
JavaType keyType = mapType.getKeyType();
if (keyType == null) { // assumed to be Object
return true;
}
Class<?> rawKeyType = keyType.getRawClass();
return ((rawKeyType == String.class || rawKeyType == Object.class)
&& isDefaultKeyDeserializer(keyDeser));
}
public void setIgnorableProperties(String[] ignorable) {
_ignorableProperties = (ignorable == null || ignorable.length == 0) ?
null : ArrayBuilders.arrayToSet(ignorable);
}
/*
/**********************************************************
/* Validation, post-processing (ResolvableDeserializer)
/**********************************************************
*/
@Override
public void resolve(DeserializationContext ctxt) throws JsonMappingException
{
// May need to resolve types for delegate- and/or property-based creators:
if (_valueInstantiator.canCreateUsingDelegate()) {
JavaType delegateType = _valueInstantiator.getDelegateType(ctxt.getConfig());
if (delegateType == null) {
throw new IllegalArgumentException("Invalid delegate-creator definition for "+_mapType
+": value instantiator ("+_valueInstantiator.getClass().getName()
+") returned true for 'canCreateUsingDelegate()', but null for 'getDelegateType()'");
}
/* Theoretically should be able to get CreatorProperty for delegate
* parameter to pass; but things get tricky because DelegateCreator
* may contain injectable values. So, for now, let's pass nothing.
*/
_delegateDeserializer = findDeserializer(ctxt, delegateType, null);
}
if (_valueInstantiator.canCreateFromObjectWith()) {
SettableBeanProperty[] creatorProps = _valueInstantiator.getFromObjectArguments(ctxt.getConfig());
_propertyBasedCreator = Property
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>p, ctxt, result);
return result;
}
_readAndBind(p, ctxt, result);
return result;
}
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException, JsonProcessingException
{
// In future could check current token... for now this should be enough:
return typeDeserializer.deserializeTypedFromObject(jp, ctxt);
}
/*
/**********************************************************
/* Other public accessors
/**********************************************************
*/
@SuppressWarnings("unchecked")
public final Class<?> getMapClass() { return (Class<Map<Object,Object>>) _mapType.getRawClass(); }
@Override public JavaType getValueType() { return _mapType; }
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
protected final void _readAndBind(JsonParser jp, DeserializationContext ctxt,
Map<Object,Object> result)
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.START_OBJECT) {
t = jp.nextToken();
}
final KeyDeserializer keyDes = _keyDeserializer;
final JsonDeserializer<Object> valueDes = _valueDeserializer;
final TypeDeserializer typeDeser = _valueTypeDeserializer;
MapReferringAccumulator referringAccumulator = null;
boolean useObjectId = valueDes.getObjectIdReader() != null;
if (useObjectId) {
referringAccumulator = new MapReferringAccumulator(_mapType.getContentType().getRawClass(), result);
}
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
// Must point to field name
String fieldName = jp.getCurrentName();
Object key = keyDes.deserializeKey(fieldName, ctxt);
// And then the value...
t = jp.nextToken();
if (_ignorableProperties != null && _ignorableProperties.contains(fieldName)) {
jp.skipChildren();
continue;
}
try{
// Note: must handle null explicitly here; value deserializers won't
Object value;
if (t == JsonToken.VALUE_NULL) {
value = valueDes.getNullValue();
} else if (typeDeser == null) {
value = valueDes.deserialize(jp, ctxt);
} else {
value = valueDes.deserializeWithType(jp, ctxt, typeDeser);
}
/* !!! 23-Dec-2008, tatu: should there be an option to verify
* that there are no duplicate field names? (and/or what
* to do, keep-first or keep-last)
*/
if (useObjectId) {
referringAccumulator.put(key, value);
} else {
result
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>);
}
Referring referring = accumulator.handleUnresolvedReference(reference, key);
reference.getRoid().appendReferring(referring);
}
private final static class MapReferringAccumulator {
private final Class<?> _valueType;
private Map<Object,Object> _result;
/**
* A list of {@link MapReferring} to maintain ordering.
*/
private List<MapReferring> _accumulator = new ArrayList<MapReferring>();
public MapReferringAccumulator(Class<?> valueType, Map<Object, Object> result) {
_valueType = valueType;
_result = result;
}
public void put(Object key, Object value)
{
if (_accumulator.isEmpty()) {
_result.put(key, value);
} else {
MapReferring ref = _accumulator.get(_accumulator.size() - 1);
ref.next.put(key, value);
}
}
public Referring handleUnresolvedReference(UnresolvedForwardReference reference, Object key)
{
MapReferring id = new MapReferring(this, reference, _valueType, key);
_accumulator.add(id);
return id;
}
public void resolveForwardReference(Object id, Object value) throws IOException
{
Iterator<MapReferring> iterator = _accumulator.iterator();
// Resolve ordering after resolution of an id. This means either:
// 1- adding to the result map in case of the first unresolved id.
// 2- merge the content of the resolved id with its previous unresolved id.
Map<Object,Object> previous = _result;
while (iterator.hasNext()) {
MapReferring ref = iterator.next();
if (ref.hasId(id)) {
iterator.remove();
previous.put(ref.key, value);
previous.putAll(ref.next);
return;
}
previous = ref.next;
}
throw new IllegalArgumentException("Trying to resolve a forward reference with id [" + id
+ "] that wasn't previously seen as unresolved.");
}
}
/**
* Helper class to maintain processing order of value. The resolved
* object associated with {@link #_id} comes before the values in
* {@link _next}.
*/
final static class MapReferring extends Referring {
private final MapReferringAccumulator _parent;
public final Map<Object, Object> next = new LinkedHashMap<Object, Object>();
public final Object key;
MapReferring(MapReferringAccumulator parent, UnresolvedForwardReference ref,
Class<?> valueType, Object key)
{
super(ref, valueType);
_parent = parent;
this.key = key;
}
@Override
public void handleResolvedForwardReference
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.introspect;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
/**
* Placeholder used by virtual properties as placeholder for
* underlying {@link AnnotatedMember}.
*
* @since 2.5
*/
public class VirtualAnnotatedMember extends AnnotatedMember
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
protected final Class<?> _declaringClass;
protected final Class<?> _rawType;
protected final String _name;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public VirtualAnnotatedMember(AnnotatedClass contextClass, Class<?> declaringClass,
String name, Class<?> rawType)
{
super(contextClass, /* AnnotationMap*/ null);
_declaringClass = declaringClass;
_rawType = rawType;
_name = name;
}
@Override
public Annotated withAnnotations(AnnotationMap fallback) {
return this;
}
/*
/**********************************************************
/* Annotated impl
/**********************************************************
*/
@Override
public Field getAnnotated() { return null; }
@Override
public int getModifiers() { return 0; }
@Override
public String getName() { return _name; }
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return null;
}
@Override
public Type getGenericType() {
return _rawType;
}
@Override
public Class<?> getRawType() {
return _rawType;
}
/*
/**********************************************************
/* AnnotatedMember impl
/**********************************************************
*/
@Override
public Class<?> getDeclaringClass() { return _declaringClass; }
@Override
public Member getMember() { return null; }
@Override
public void setValue(Object pojo, Object value) throws IllegalArgumentException {
throw new IllegalArgumentException("Can not set virtual property '"+_name+"'");
}
@Override
public Object getValue(Object pojo) throws IllegalArgumentException {
throw new IllegalArgumentException("Can not get virtual property '"+_name+"'");
}
/*
/**********************************************************
/* Extended API, generic
/**********************************************************
*/
public String getFullName() {
return getDeclaringClass().getName() + "#" + getName();
}
public int getAnnotationCount() { return 0; }
@Override
public int hashCode() {
return _name.hashCode();
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (o == null || o.getClass() != getClass()) return false;
VirtualAnnotatedMember other = (VirtualAnnotatedMember) o;
return (other._declaringClass
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.type;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonSerializable;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
public abstract class TypeBase
extends JavaType
implements JsonSerializable
{
private static final long serialVersionUID = -3581199092426900829L;
/**
* Lazily initialized external representation of the type
*/
volatile transient String _canonicalName;
/**
* @deprecated Since 2.2 use method that takes 'asStatic' argument
*/
@Deprecated
protected TypeBase(Class<?> raw, int hash,
Object valueHandler, Object typeHandler)
{
this(raw, hash, valueHandler, typeHandler, false);
}
/**
* Main constructor to use by extending classes.
*/
protected TypeBase(Class<?> raw, int hash,
Object valueHandler, Object typeHandler, boolean asStatic)
{
super(raw, hash, valueHandler, typeHandler, asStatic);
}
@Override
public String toCanonical()
{
String str = _canonicalName;
if (str == null) {
str = buildCanonicalName();
}
return str;
}
protected abstract String buildCanonicalName();
@Override
public abstract StringBuilder getGenericSignature(StringBuilder sb);
@Override
public abstract StringBuilder getErasedSignature(StringBuilder sb);
@Override
@SuppressWarnings("unchecked")
public <T> T getValueHandler() { return (T) _valueHandler; }
@Override
@SuppressWarnings("unchecked")
public <T> T getTypeHandler() { return (T) _typeHandler; }
/*
/**********************************************************
/* JsonSerializableWithType base implementation
/**********************************************************
*/
@Override
public void serializeWithType(JsonGenerator jgen, SerializerProvider provider,
TypeSerializer typeSer)
throws IOException, JsonProcessingException
{
typeSer.writeTypePrefixForScalar(this, jgen);
this.serialize(jgen, provider);
typeSer.writeTypeSuffixForScalar(this, jgen);
}
@Override
public void serialize(JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException
{
jgen.writeString(toCanonical());
}
/*
/**********************************************************
/* Methods for sub-classes to use
/**********************************************************
*/
/**
* @param trailingSemicolon Whether to add trailing semicolon for non-primitive
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> * (reference) types or not
*/
protected static StringBuilder _classSignature(Class<?> cls, StringBuilder sb,
boolean trailingSemicolon)
{
if (cls.isPrimitive()) {
if (cls == Boolean.TYPE) {
sb.append('Z');
} else if (cls == Byte.TYPE) {
sb.append('B');
}
else if (cls == Short.TYPE) {
sb.append('S');
}
else if (cls == Character.TYPE) {
sb.append('C');
}
else if (cls == Integer.TYPE) {
sb.append('I');
}
else if (cls == Long.TYPE) {
sb.append('J');
}
else if (cls == Float.TYPE) {
sb.append('F');
}
else if (cls == Double.TYPE) {
sb.append('D');
}
else if (cls == Void.TYPE) {
sb.append('V');
} else {
throw new IllegalStateException("Unrecognized primitive type: "+cls.getName());
}
} else {
sb.append('L');
String name = cls.getName();
for (int i = 0, len = name.length(); i < len; ++i) {
char c = name.charAt(i);
if (c == '.') c = '/';
sb.append(c);
}
if (trailingSemicolon) {
sb.append(';');
}
}
return sb;
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.impl;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.introspect.*;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.util.Annotations;
/**
* This concrete sub-class implements property that is set
* using regular "setter" method.
*/
public final class MethodProperty
extends SettableBeanProperty
{
private static final long serialVersionUID = 1;
protected final AnnotatedMethod _annotated;
/**
* Setter method for modifying property value; used for
* "regular" method-accessible properties.
*/
protected final transient Method _setter;
public MethodProperty(BeanPropertyDefinition propDef,
JavaType type, TypeDeserializer typeDeser,
Annotations contextAnnotations, AnnotatedMethod method)
{
super(propDef, type, typeDeser, contextAnnotations);
_annotated = method;
_setter = method.getAnnotated();
}
protected MethodProperty(MethodProperty src, JsonDeserializer<?> deser) {
super(src, deser);
_annotated = src._annotated;
_setter = src._setter;
}
protected MethodProperty(MethodProperty src, PropertyName newName) {
super(src, newName);
_annotated = src._annotated;
_setter = src._setter;
}
/**
* Constructor used for JDK Serialization when reading persisted object
*/
protected MethodProperty(MethodProperty src, Method m) {
super(src);
_annotated = src._annotated;
_setter = m;
}
@Override
public MethodProperty withName(PropertyName newName) {
return new MethodProperty(this, newName);
}
@Override
public MethodProperty withValueDeserializer(JsonDeserializer<?> deser) {
return new MethodProperty(this, deser);
}
/*
/**********************************************************
/* BeanProperty impl
/**********************************************************
*/
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return _annotated.getAnnotation(acls);
}
@Override public AnnotatedMember getMember() { return _annotated; }
/*
/**********************************************************
/* Overridden methods
/**********************************************************
*/
@Override
public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt,
Object instance) throws IOException
{
Object value = deserialize(jp, ctxt);
try {
_setter.invoke(instance, value
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> ctxt));
case FIELD_NAME:
case END_OBJECT: // added to resolve [JACKSON-319], possible related issues
return finishBuild(ctxt, deserializeFromObject(jp, ctxt));
default:
throw ctxt.mappingException(handledType());
}
}
/**
* Secondary deserialization method, called in cases where POJO
* instance is created as part of deserialization, potentially
* after collecting some or all of the properties to set.
*/
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt,
Object builder)
throws IOException, JsonProcessingException
{
/* Important: we call separate method which does NOT call
* 'finishBuild()', to avoid problems with recursion
*/
return finishBuild(ctxt, _deserialize(jp, ctxt, builder));
}
/*
/**********************************************************
/* Concrete deserialization methods
/**********************************************************
*/
protected final Object _deserialize(JsonParser jp,
DeserializationContext ctxt, Object builder)
throws IOException, JsonProcessingException
{
if (_injectables != null) {
injectValues(ctxt, builder);
}
if (_unwrappedPropertyHandler != null) {
return deserializeWithUnwrapped(jp, ctxt, builder);
}
if (_externalTypeIdHandler != null) {
return deserializeWithExternalTypeId(jp, ctxt, builder);
}
if (_needViewProcesing) {
Class<?> view = ctxt.getActiveView();
if (view != null) {
return deserializeWithView(jp, ctxt, builder, view);
}
}
JsonToken t = jp.getCurrentToken();
// 23-Mar-2010, tatu: In some cases, we start with full JSON object too...
if (t == JsonToken.START_OBJECT) {
t = jp.nextToken();
}
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
// Skip field name:
jp.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) { // normal case
try {
builder = prop.deserializeSetAndReturn(jp, ctxt, builder);
} catch (Exception e) {
wrapAndThrow(e, builder, propName, ctxt);
}
continue;
}
handleUnknownVanilla(jp, ctxt, handledType(), propName);
}
return builder;
}
/**
* Streamlined version that is only used when no "special"
* features are enabled.
*/
private final Object vanillaDeserialize(JsonParser jp,
DeserializationContext ctxt, JsonToken t)
throws IOException, JsonProcessingException
{
Object bean = _value
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Instantiator.createUsingDefault(ctxt);
for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) {
String propName = jp.getCurrentName();
// Skip field name:
jp.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) { // normal case
try {
bean = prop.deserializeSetAndReturn(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
} else {
handleUnknownVanilla(jp, ctxt, bean, propName);
}
}
return bean;
}
/**
* General version used when handling needs more advanced
* features.
*/
@Override
public Object deserializeFromObject(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
if (_nonStandardCreation) {
if (_unwrappedPropertyHandler != null) {
return deserializeWithUnwrapped(jp, ctxt);
}
if (_externalTypeIdHandler != null) {
return deserializeWithExternalTypeId(jp, ctxt);
}
return deserializeFromObjectUsingNonDefault(jp, ctxt);
}
Object bean = _valueInstantiator.createUsingDefault(ctxt);
if (_injectables != null) {
injectValues(ctxt, bean);
}
if (_needViewProcesing) {
Class<?> view = ctxt.getActiveView();
if (view != null) {
return deserializeWithView(jp, ctxt, bean, view);
}
}
for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) {
String propName = jp.getCurrentName();
// Skip field name:
jp.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) { // normal case
try {
bean = prop.deserializeSetAndReturn(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
handleUnknownVanilla(jp, ctxt, bean, propName);
}
return bean;
}
/**
* Method called to deserialize bean using "property-based creator":
* this means that a non-default constructor or factory method is
* called, and then possibly other setters. The trick is that
* values for creator method need to be buffered, first; and
* due to non-guaranteed ordering possibly some other properties
* as well.
*/
@Override
@SuppressWarnings("resource")
protected final Object _deserializeUsingPropertyBased(final JsonParser jp,
final DeserializationContext ctxt)
throws IOException,
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>, so:
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapInstantiationProblem(e, ctxt);
return null; // never gets here
}
if (unknown != null) {
// polymorphic?
if (bean.getClass() != _beanType.getRawClass()) {
return handlePolymorphic(null, ctxt, bean, unknown);
}
// no, just some extra unknown properties
return handleUnknownProperties(ctxt, bean, unknown);
}
return bean;
}
/*
/**********************************************************
/* Deserializing when we have to consider an active View
/**********************************************************
*/
protected final Object deserializeWithView(JsonParser jp, DeserializationContext ctxt,
Object bean, Class<?> activeView)
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
// Skip field name:
jp.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) {
if (!prop.visibleInView(activeView)) {
jp.skipChildren();
continue;
}
try {
bean = prop.deserializeSetAndReturn(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
handleUnknownVanilla(jp, ctxt, bean, propName);
}
return bean;
}
/*
/**********************************************************
/* Handling for cases where we have "unwrapped" values
/**********************************************************
*/
/**
* Method called when there are declared "unwrapped" properties
* which need special handling
*/
@SuppressWarnings("resource")
protected Object deserializeWithUnwrapped(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
if (_delegateDeserializer != null) {
return _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt));
}
if (_propertyBasedCreator != null) {
return deserializeUsingPropertyBasedWithUnwrapped(jp, ctxt);
}
TokenBuffer tokens = new TokenBuffer(jp);
tokens.writeStartObject();
Object bean = _valueInstantiator.createUsingDefault(ctxt);
if (_injectables != null) {
injectValues(ctxt, bean);
}
final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) {
String propName = jp.getCurrentName();
jp.nextToken();
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) { // normal case
if (activeView != null && !prop.visibleInView(activeView)) {
jp.skipChildren();
continue;
}
try {
bean = prop.deserializeSetAndReturn(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
// ignorable things should be ignored
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, bean, propName);
continue;
}
// but... others should be passed to unwrapped property deserializers
tokens.writeFieldName(propName);
tokens.copyCurrentStructure(jp);
// how about any setter? We'll get copies but...
if (_anySetter != null) {
try {
_anySetter.deserializeAndSet(jp, ctxt, bean, propName);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
}
tokens.writeEndObject();
_unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens);
return bean;
}
@SuppressWarnings("resource")
protected Object deserializeWithUnwrapped(JsonParser jp,
DeserializationContext ctxt, Object bean)
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.START_OBJECT) {
t = jp.nextToken();
}
TokenBuffer tokens = new TokenBuffer(jp);
tokens.writeStartObject();
final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) {
String propName = jp.getCurrentName();
SettableBeanProperty prop = _beanProperties.find(propName);
jp.nextToken();
if (prop != null) { // normal case
if (activeView != null && !prop.visibleInView(activeView)) {
jp.skipChildren();
continue;
}
try {
bean = prop.deserializeSetAndReturn(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, bean, propName);
continue;
}
// but... others should be passed to unwrapped property deserializers
tokens.writeFieldName(propName);
tokens.copy
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, handledType(), propName);
continue;
}
tokens.writeFieldName(propName);
tokens.copyCurrentStructure(jp);
// "any property"?
if (_anySetter != null) {
buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(jp, ctxt));
}
}
// We hit END_OBJECT, so:
Object bean;
// !!! 15-Feb-2012, tatu: Need to modify creator to use Builder!
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapInstantiationProblem(e, ctxt);
return null; // never gets here
}
return _unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens);
}
/*
/**********************************************************
/* Handling for cases where we have property/-ies with
/* external type id
/**********************************************************
*/
protected Object deserializeWithExternalTypeId(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
if (_propertyBasedCreator != null) {
return deserializeUsingPropertyBasedWithExternalTypeId(jp, ctxt);
}
return deserializeWithExternalTypeId(jp, ctxt, _valueInstantiator.createUsingDefault(ctxt));
}
protected Object deserializeWithExternalTypeId(JsonParser jp,
DeserializationContext ctxt, Object bean)
throws IOException, JsonProcessingException
{
final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
final ExternalTypeHandler ext = _externalTypeIdHandler.start();
for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) {
String propName = jp.getCurrentName();
jp.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) { // normal case
if (activeView != null && !prop.visibleInView(activeView)) {
jp.skipChildren();
continue;
}
try {
bean = prop.deserializeSetAndReturn(jp, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
// ignorable things should be ignored
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(jp, ctxt, bean, propName);
continue;
}
// but others are likely to be part of external type id thingy...
if (ext.handlePropertyValue(jp, ctxt, propName, bean)) {
continue;
}
// if not, the usual fallback handling:
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.impl;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.PropertyName;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.util.Annotations;
/**
* This concrete sub-class implements Collection or Map property that is
* indirectly by getting the property value and directly modifying it.
*/
public final class SetterlessProperty
extends SettableBeanProperty
{
private static final long serialVersionUID = 1L;
protected final AnnotatedMethod _annotated;
/**
* Get method for accessing property value used to access property
* (of Collection or Map type) to modify.
*/
protected final Method _getter;
public SetterlessProperty(BeanPropertyDefinition propDef, JavaType type,
TypeDeserializer typeDeser, Annotations contextAnnotations, AnnotatedMethod method) {
super(propDef, type, typeDeser, contextAnnotations);
_annotated = method;
_getter = method.getAnnotated();
}
protected SetterlessProperty(SetterlessProperty src, JsonDeserializer<?> deser) {
super(src, deser);
_annotated = src._annotated;
_getter = src._getter;
}
protected SetterlessProperty(SetterlessProperty src, PropertyName newName) {
super(src, newName);
_annotated = src._annotated;
_getter = src._getter;
}
@Override
public SetterlessProperty withName(PropertyName newName) {
return new SetterlessProperty(this, newName);
}
@Override
public SetterlessProperty withValueDeserializer(JsonDeserializer<?> deser) {
return new SetterlessProperty(this, deser);
}
/*
/**********************************************************
/* BeanProperty impl
/**********************************************************
*/
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return _annotated.getAnnotation(
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Class.construct(type.getRawClass(), ai, r);
JsonPOJOBuilder.Value builderConfig = (ai == null) ? null : ai.findPOJOBuilderConfig(ac);
String mutatorPrefix = (builderConfig == null) ? "with" : builderConfig.withPrefix;
return constructPropertyCollector(config, ac, type, forSerialization, mutatorPrefix).collect();
}
/**
* Overridable method called for creating {@link POJOPropertiesCollector} instance
* to use; override is needed if a custom sub-class is to be used.
*/
protected POJOPropertiesCollector constructPropertyCollector(MapperConfig<?> config,
AnnotatedClass ac, JavaType type, boolean forSerialization, String mutatorPrefix)
{
return new POJOPropertiesCollector(config, forSerialization, type, ac, mutatorPrefix);
}
/**
* Method called to see if type is one of core JDK types
* that we have cached for efficiency.
*/
protected BasicBeanDescription _findStdTypeDesc(JavaType type)
{
Class<?> cls = type.getRawClass();
if (cls.isPrimitive()) {
if (cls == Boolean.TYPE) {
return BOOLEAN_DESC;
}
if (cls == Integer.TYPE) {
return INT_DESC;
}
if (cls == Long.TYPE) {
return LONG_DESC;
}
} else {
if (cls == String.class) {
return STRING_DESC;
}
}
return null;
}
/**
* Helper method used to decide whether we can omit introspection
* for members (methods, fields, constructors); we may do so for
* a limited number of container types JDK provides.
*/
protected boolean _isStdJDKCollection(JavaType type)
{
if (!type.isContainerType() || type.isArrayType()) {
return false;
}
Class<?> raw = type.getRawClass();
Package pkg = raw.getPackage();
if (pkg != null) {
String pkgName = pkg.getName();
if (pkgName.startsWith("java.lang")
|| pkgName.startsWith("java.util")) {
/* 23-Sep-2014, tatu: Should we be conservative here (minimal number
* of matches), or ambitious? Let's do latter for now.
*/
if (Collection.class.isAssignableFrom(raw)
|| Map.class.isAssignableFrom(raw)) {
return true;
}
}
}
return false;
}
protected BasicBeanDescription _findStdJdkCollectionDesc(MapperConfig<?> cfg,
JavaType type, MixInResolver r)
{
if (_isStdJDKCollection(type)) {
Annot
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser;
import java.io.IOException;
import java.util.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.impl.ObjectIdReader;
import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
/**
* Deserializer only used for abstract types used as placeholders during polymorphic
* type handling deserialization. If so, there is no real deserializer associated
* with nominal type, just {@link TypeDeserializer}; and any calls that do not
* pass such resolver will result in an error.
*/
public class AbstractDeserializer
extends JsonDeserializer<Object>
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
protected final JavaType _baseType;
protected final ObjectIdReader _objectIdReader;
protected final Map<String, SettableBeanProperty> _backRefProperties;
// support for "native" types, which require special care:
protected final boolean _acceptString;
protected final boolean _acceptBoolean;
protected final boolean _acceptInt;
protected final boolean _acceptDouble;
public AbstractDeserializer(BeanDeserializerBuilder builder,
BeanDescription beanDesc, Map<String, SettableBeanProperty> backRefProps)
{
_baseType = beanDesc.getType();
_objectIdReader = builder.getObjectIdReader();
_backRefProperties = backRefProps;
Class<?> cls = _baseType.getRawClass();
_acceptString = cls.isAssignableFrom(String.class);
_acceptBoolean = (cls == Boolean.TYPE) || cls.isAssignableFrom(Boolean.class);
_acceptInt = (cls == Integer.TYPE) || cls.isAssignableFrom(Integer.class);
_acceptDouble = (cls == Double.TYPE) || cls.isAssignableFrom(Double.class);
}
protected AbstractDeserializer(BeanDescription beanDesc)
{
_baseType = beanDesc.getType();
_objectIdReader = null;
_backRefProperties = null;
Class<?> cls = _baseType.getRawClass();
_acceptString = cls.isAssignableFrom(String.class);
_acceptBoolean = (cls == Boolean.TYPE) || cls.isAssignableFrom(Boolean.class);
_acceptInt = (cls == Integer.TYPE) || cls.isAssignableFrom(Integer.class);
_acceptDouble = (cls == Double.TYPE) || cls.isAssignableFrom(Double.class);
}
/**
* Factory method used when constructing instances for non-POJO types, like
* {@link java.util.Map}s.
*
* @since 2.3
*/
public static
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> AbstractDeserializer constructForNonPOJO(BeanDescription beanDesc) {
return new AbstractDeserializer(beanDesc);
}
/*
/**********************************************************
/* Public accessors
/**********************************************************
*/
@Override
public Class<?> handledType() {
return _baseType.getRawClass();
}
@Override
public boolean isCachable() { return true; }
/**
* Overridden to return true for those instances that are
* handling value for which Object Identity handling is enabled
* (either via value type or referring property).
*/
@Override
public ObjectIdReader getObjectIdReader() {
return _objectIdReader;
}
/**
* Method called by <code>BeanDeserializer</code> to resolve back reference
* part of managed references.
*/
@Override
public SettableBeanProperty findBackReference(String logicalName) {
return (_backRefProperties == null) ? null : _backRefProperties.get(logicalName);
}
/*
/**********************************************************
/* Deserializer implementation
/**********************************************************
*/
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException, JsonProcessingException
{
// Hmmh. One tricky question; for scalar, is it an Object Id, or "Natural" type?
// for now, prefer Object Id:
if (_objectIdReader != null) {
JsonToken t = jp.getCurrentToken();
// should be good enough check; we only care about Strings, integral numbers:
if (t != null && t.isScalarValue()) {
return _deserializeFromObjectId(jp, ctxt);
}
}
// First: support "natural" values (which are always serialized without type info!)
Object result = _deserializeIfNatural(jp, ctxt);
if (result != null) {
return result;
}
return typeDeserializer.deserializeTypedFromObject(jp, ctxt);
}
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
// This method should never be called...
throw ctxt.instantiationException(_baseType.getRawClass(),
"abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information");
}
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
protected Object _deserializeIfNatural(JsonParser jp, DeserializationContext ctxt) throws IOException
{
/* As per [JACKSON-417], there is a chance we might be "natural" types
* (String, Boolean, Integer, Double), which do not include any type information...
* Care must be taken to only return this if return type matches, however.
* Finally, we may have to consider possibility
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> JsonInclude.Include findSerializationInclusionForContent(Annotated a, JsonInclude.Include defValue)
{
// note: call secondary first, to give lower priority
defValue = _secondary.findSerializationInclusion(a, defValue);
defValue = _primary.findSerializationInclusion(a, defValue);
return defValue;
}
@Override
public Class<?> findSerializationType(Annotated a) {
Class<?> r = _primary.findSerializationType(a);
return (r == null) ? _secondary.findSerializationType(a) : r;
}
@Override
public Class<?> findSerializationKeyType(Annotated am, JavaType baseType) {
Class<?> r = _primary.findSerializationKeyType(am, baseType);
return (r == null) ? _secondary.findSerializationKeyType(am, baseType) : r;
}
@Override
public Class<?> findSerializationContentType(Annotated am, JavaType baseType) {
Class<?> r = _primary.findSerializationContentType(am, baseType);
return (r == null) ? _secondary.findSerializationContentType(am, baseType) : r;
}
@Override
public JsonSerialize.Typing findSerializationTyping(Annotated a) {
JsonSerialize.Typing r = _primary.findSerializationTyping(a);
return (r == null) ? _secondary.findSerializationTyping(a) : r;
}
@Override
public Object findSerializationConverter(Annotated a) {
Object r = _primary.findSerializationConverter(a);
return (r == null) ? _secondary.findSerializationConverter(a) : r;
}
@Override
public Object findSerializationContentConverter(AnnotatedMember a) {
Object r = _primary.findSerializationContentConverter(a);
return (r == null) ? _secondary.findSerializationContentConverter(a) : r;
}
@Override
public Class<?>[] findViews(Annotated a) {
/* Theoretically this could be trickier, if multiple introspectors
* return non-null entries. For now, though, we'll just consider
* first one to return non-null to win.
*/
Class<?>[] result = _primary.findViews(a);
if (result == null) {
result = _secondary.findViews(a);
}
return result;
}
@Override
public Boolean isTypeId(AnnotatedMember member) {
Boolean b = _primary.isTypeId(member);
return (b == null) ? _secondary.isTypeId(member) : b;
}
@Override
public ObjectIdInfo findObjectIdInfo(Annotated ann) {
ObjectIdInfo r = _primary.findObjectIdInfo(ann);
return (r == null) ? _secondary.findObjectIdInfo
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>) ? _secondary.findSerializationSortAlphabetically(ac) : r;
}
@Override
public Boolean findSerializationSortAlphabetically(Annotated ann) {
Boolean r = _primary.findSerializationSortAlphabetically(ann);
return (r == null) ? _secondary.findSerializationSortAlphabetically(ann) : r;
}
@Override
public void findAndAddVirtualProperties(MapperConfig<?> config, AnnotatedClass ac,
List<BeanPropertyWriter> properties) {
// first secondary, then primary, to give proper precedence
_primary.findAndAddVirtualProperties(config, ac, properties);
_secondary.findAndAddVirtualProperties(config, ac, properties);
}
// // // Serialization: property annotations
@Override
public PropertyName findNameForSerialization(Annotated a) {
PropertyName n = _primary.findNameForSerialization(a);
// note: "use default" should not block explicit answer, so:
if (n == null) {
n = _secondary.findNameForSerialization(a);
} else if (n == PropertyName.USE_DEFAULT) {
PropertyName n2 = _secondary.findNameForSerialization(a);
if (n2 != null) {
n = n2;
}
}
return n;
}
@Override
public boolean hasAsValueAnnotation(AnnotatedMethod am) {
return _primary.hasAsValueAnnotation(am) || _secondary.hasAsValueAnnotation(am);
}
@Override
public String findEnumValue(Enum<?> value) {
String r = _primary.findEnumValue(value);
return (r == null) ? _secondary.findEnumValue(value) : r;
}
// // // Deserialization: general annotations
@Override
public Object findDeserializer(Annotated am) {
Object r = _primary.findDeserializer(am);
return _isExplicitClassOrOb(r, JsonDeserializer.None.class)
? r : _secondary.findDeserializer(am);
}
@Override
public Object findKeyDeserializer(Annotated am) {
Object r = _primary.findKeyDeserializer(am);
return _isExplicitClassOrOb(r, KeyDeserializer.None.class)
? r : _secondary.findKeyDeserializer(am);
}
@Override
public Object findContentDeserializer(Annotated am) {
Object r = _primary.findContentDeserializer(am);
return _isExplicitClassOrOb(r, JsonDeserializer.None.class)
? r : _secondary.findContentDeserializer(am);
}
@Override
public Class<?> findDeserializationType(Annotated am, JavaType baseType) {
Class<?> r = _primary.findDeserializationType(am, baseType);
return (r != null)
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> ? r : _secondary.findDeserializationType(am, baseType);
}
@Override
public Class<?> findDeserializationKeyType(Annotated am, JavaType baseKeyType) {
Class<?> result = _primary.findDeserializationKeyType(am, baseKeyType);
return (result == null) ? _secondary.findDeserializationKeyType(am, baseKeyType) : result;
}
@Override
public Class<?> findDeserializationContentType(Annotated am, JavaType baseContentType) {
Class<?> result = _primary.findDeserializationContentType(am, baseContentType);
return (result == null) ? _secondary.findDeserializationContentType(am, baseContentType) : result;
}
@Override
public Object findDeserializationConverter(Annotated a) {
Object ob = _primary.findDeserializationConverter(a);
return (ob == null) ? _secondary.findDeserializationConverter(a) : ob;
}
@Override
public Object findDeserializationContentConverter(AnnotatedMember a) {
Object ob = _primary.findDeserializationContentConverter(a);
return (ob == null) ? _secondary.findDeserializationContentConverter(a) : ob;
}
// // // Deserialization: class annotations
@Override
public Object findValueInstantiator(AnnotatedClass ac) {
Object result = _primary.findValueInstantiator(ac);
return (result == null) ? _secondary.findValueInstantiator(ac) : result;
}
@Override
public Class<?> findPOJOBuilder(AnnotatedClass ac) {
Class<?> result = _primary.findPOJOBuilder(ac);
return (result == null) ? _secondary.findPOJOBuilder(ac) : result;
}
@Override
public JsonPOJOBuilder.Value findPOJOBuilderConfig(AnnotatedClass ac) {
JsonPOJOBuilder.Value result = _primary.findPOJOBuilderConfig(ac);
return (result == null) ? _secondary.findPOJOBuilderConfig(ac) : result;
}
// // // Deserialization: method annotations
@Override
public PropertyName findNameForDeserialization(Annotated a)
{
// note: "use default" should not block explicit answer, so:
PropertyName n = _primary.findNameForDeserialization(a);
if (n == null) {
n = _secondary.findNameForDeserialization(a);
} else if (n == PropertyName.USE_DEFAULT) {
PropertyName n2 = _secondary.findNameForDeserialization(a);
if (n2 != null) {
n = n2;
}
}
return n;
}
@Override
public boolean hasAnySetterAnnotation(AnnotatedMethod am) {
return _primary.hasAnySetterAnnotation(am) || _secondary.hasAnySetterAnnotation(am);
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
@Override
public boolean hasAnyGetterAnnotation(AnnotatedMethod am) {
return _primary.hasAnyGetterAnnotation(am) || _secondary.hasAnyGetterAnnotation(am);
}
@Override
public boolean hasCreatorAnnotation(Annotated a) {
return _primary.hasCreatorAnnotation(a) || _secondary.hasCreatorAnnotation(a);
}
@Override
public JsonCreator.Mode findCreatorBinding(Annotated a) {
JsonCreator.Mode mode = _primary.findCreatorBinding(a);
if (mode != null) {
return mode;
}
return _secondary.findCreatorBinding(a);
}
protected boolean _isExplicitClassOrOb(Object maybeCls, Class<?> implicit) {
if (maybeCls == null) {
return false;
}
if (!(maybeCls instanceof Class<?>)) {
return true;
}
Class<?> cls = (Class<?>) maybeCls;
return (cls != implicit && !ClassUtil.isBogusClass(cls));
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> Configuration in effect
* @param beanDesc Definition of the enumeration type that contains class annotations and
* other information typically needed for building deserializers
*
* @return Deserializer to use for the type; or null if this provider does not know how to construct it
*/
public JsonDeserializer<?> findEnumDeserializer(Class<?> type,
DeserializationConfig config, BeanDescription beanDesc)
throws JsonMappingException;
/**
* Method called to locate deserializer for specified {@link java.util.Map} type.
*<p>
* Deserializer for element type may be passed, if configured explicitly at higher level (by
* annotations, typically), but usually are not.
* Type deserializer for element is passed if one is needed based on contextual information
* (annotations on declared element class; or on field or method type is associated with).
*<p>
* Similarly, a {@link KeyDeserializer} may be passed, but this is only done if there is
* a specific configuration override (annotations) to indicate instance to use.
* Otherwise null is passed, and key deserializer needs to be obtained later during
* resolution (using {@link ResolvableDeserializer#resolve}).
*
* @param type Type of {@link java.util.Map} instances to deserialize
* @param config Configuration in effect
* @param beanDesc Definition of the enumeration type that contains class annotations and
* other information typically needed for building deserializers
* @param keyDeserializer Key deserializer use, if it is defined via annotations or other configuration;
* null if default key deserializer for key type can be used.
* @param elementTypeDeserializer If element type needs polymorphic type handling, this is
* the type information deserializer to use; should usually be used as is when constructing
* array deserializer.
* @param elementDeserializer Deserializer to use for elements, if explicitly defined (by using
* annotations, for exmple). May be null, in which case it should be resolved here (or using
* {@link ResolvableDeserializer} callback)
*
* @return Deserializer to use for the type; or null if this provider does not know how to construct it
*/
public JsonDeserializer<?> findMapDeserializer(MapType type,
DeserializationConfig config, BeanDescription beanDesc,
KeyDeserializer keyDeserializer,
TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer)
throws JsonMappingException;
/**
* Method called to locate serializer for specified
* "Map-like" type (one that acts
* like {@link java.util.Map} but does not implement it).
*<p>
* Deserializer for element type may be passed, if configured explicitly at higher level (by
* annotations, typically), but usually are not.
* Type
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> deserializer for element is passed if one is needed based on contextual information
* (annotations on declared element class; or on field or method type is associated with).
*<p>
* Similarly, a {@link KeyDeserializer} may be passed, but this is only done if there is
* a specific configuration override (annotations) to indicate instance to use.
* Otherwise null is passed, and key deserializer needs to be obtained later during
* resolution (using {@link ResolvableDeserializer#resolve}).
*
* @param type Type of {@link java.util.Map} instances to deserialize
* @param config Configuration in effect
* @param beanDesc Definition of the enumeration type that contains class annotations and
* other information typically needed for building deserializers
* @param keyDeserializer Key deserializer use, if it is defined via annotations or other configuration;
* null if default key deserializer for key type can be used.
* @param elementTypeDeserializer If element type needs polymorphic type handling, this is
* the type information deserializer to use; should usually be used as is when constructing
* array deserializer.
* @param elementDeserializer Deserializer to use for elements, if explicitly defined (by using
* annotations, for exmple). May be null, in which case it should be resolved here (or using
* {@link ResolvableDeserializer} callback)
*
* @return Deserializer to use for the type; or null if this provider does not know how to construct it
*/
public JsonDeserializer<?> findMapLikeDeserializer(MapLikeType type,
DeserializationConfig config, BeanDescription beanDesc,
KeyDeserializer keyDeserializer,
TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer)
throws JsonMappingException;
/**
* Method called to locate deserializer for specified JSON tree node type.
*
* @param nodeType Specific type of JSON tree nodes to deserialize
* (subtype of {@link com.fasterxml.jackson.databind.JsonNode})
* @param config Configuration in effect
*
* @return Deserializer to use for the type; or null if this provider does not know how to construct it
*/
public JsonDeserializer<?> findTreeNodeDeserializer(Class<? extends JsonNode> nodeType,
DeserializationConfig config, BeanDescription beanDesc)
throws JsonMappingException;
/**
* Method called to locate deserializer for specified value type which does not belong to any other
* category (not an Enum, Collection, Map, Array or tree node)
*
* @param type Bean type to deserialize
* @param config Configuration in effect
* @param beanDesc Definition of the enumeration type that contains class annotations and
* other information typically needed for building deserializers
*
* @return Deserializer to use for the type; or null if this provider
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> does not know how to construct it
*/
public JsonDeserializer<?> findBeanDeserializer(JavaType type,
DeserializationConfig config, BeanDescription beanDesc)
throws JsonMappingException;
/*
/**********************************************************
/* Helper classes
/**********************************************************
*/
/**
* Basic {@link Deserializers} implementation that implements all methods but provides
* no deserializers. Its main purpose is to serve as a base class so that
* sub-classes only need to override methods they need, as most of the time some
* of methods are not needed (especially enumeration and array deserializers are
* very rarely overridden).
*/
public static class Base implements Deserializers
{
@Override
public JsonDeserializer<?> findArrayDeserializer(ArrayType type,
DeserializationConfig config, BeanDescription beanDesc,
TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer)
throws JsonMappingException
{
return null;
}
@Override
public JsonDeserializer<?> findCollectionDeserializer(CollectionType type,
DeserializationConfig config, BeanDescription beanDesc,
TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer)
throws JsonMappingException
{
return null;
}
@Override
public JsonDeserializer<?> findCollectionLikeDeserializer(CollectionLikeType type,
DeserializationConfig config, BeanDescription beanDesc,
TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer)
throws JsonMappingException
{
return null;
}
@Override
public JsonDeserializer<?> findMapDeserializer(MapType type,
DeserializationConfig config, BeanDescription beanDesc,
KeyDeserializer keyDeserializer,
TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer)
throws JsonMappingException
{
return null;
}
@Override
public JsonDeserializer<?> findMapLikeDeserializer(MapLikeType type,
DeserializationConfig config, BeanDescription beanDesc,
KeyDeserializer keyDeserializer,
TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer)
throws JsonMappingException
{
return null;
}
@Override
public JsonDeserializer<?> findEnumDeserializer(Class<?> type,
DeserializationConfig config, BeanDescription beanDesc)
throws JsonMappingException
{
return null;
}
@Override
public JsonDeserializer<?> findTreeNodeDeserializer(Class<? extends JsonNode> nodeType,
DeserializationConfig config, BeanDescription beanDesc)
throws JsonMappingException
{
return null;
}
@Override
public JsonDeserializer<?> findBeanDeserializer(JavaType type,
DeserializationConfig config, BeanDescription beanDesc)
throws JsonMappingException
{
return null;
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.type;
import java.util.*;
import com.fasterxml.jackson.databind.JavaType;
/**
* Simple types are defined as anything other than one of recognized
* container types (arrays, Collections, Maps). For our needs we
* need not know anything further, since we have no way of dealing
* with generic types other than Collections and Maps.
*/
public final class SimpleType
extends TypeBase
{
private static final long serialVersionUID = -800374828948534376L;
/**
* In case there are resolved type parameters, this field stores reference
* to that type. It must be {@link #getRawClass()} or its supertype.
*
* @since 2.5
*/
protected final Class<?> _typeParametersFor;
/**
* Generic type arguments for this type.
*/
protected final JavaType[] _typeParameters;
/**
* Names of generic type arguments for this type; will
* match values in {@link #_typeParameters}
*/
protected final String[] _typeNames;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
protected SimpleType(Class<?> cls) {
this(cls, null, null, null, null, false, null);
}
/**
* @deprecated Since 2.5 use variant that takes one more argument
*/
@Deprecated
protected SimpleType(Class<?> cls, String[] typeNames, JavaType[] typeParams,
Object valueHandler, Object typeHandler, boolean asStatic)
{
this(cls, typeNames, typeParams, valueHandler, typeHandler, asStatic, null);
}
/**
*
* @param parametersFrom Interface or abstract class implemented by this type,
* and for which type parameters apply. It may be <code>cls</code> itself,
* but more commonly it is one of its supertypes.
*/
protected SimpleType(Class<?> cls,
String[] typeNames, JavaType[] typeParams,
Object valueHandler, Object typeHandler, boolean asStatic,
Class<?> parametersFrom)
{
super(cls, 0, valueHandler, typeHandler, asStatic);
if (typeNames == null || typeNames.length == 0) {
_typeNames = null;
_typeParameters = null;
} else {
_typeNames = typeNames;
_typeParameters = typeParams;
}
_typeParametersFor = parametersFrom;
}
/**
* Method used by core Jackson classes: NOT to be used by application code.
*<p>
* NOTE: public only because it is called by <code>ObjectMapper</code> which is
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> * not in same package
*/
public static SimpleType constructUnsafe(Class<?> raw) {
return new SimpleType(raw, null, null, null, null, false, null);
}
@Override
protected JavaType _narrow(Class<?> subclass)
{
// Should we check that there is a sub-class relationship?
return new SimpleType(subclass, _typeNames, _typeParameters, _valueHandler, _typeHandler,
_asStatic, _typeParametersFor);
}
@Override
public JavaType narrowContentsBy(Class<?> subclass)
{
// should never get called
throw new IllegalArgumentException("Internal error: SimpleType.narrowContentsBy() should never be called");
}
@Override
public JavaType widenContentsBy(Class<?> subclass)
{
// should never get called
throw new IllegalArgumentException("Internal error: SimpleType.widenContentsBy() should never be called");
}
public static SimpleType construct(Class<?> cls)
{
/* Let's add sanity checks, just to ensure no
* Map/Collection entries are constructed
*/
if (Map.class.isAssignableFrom(cls)) {
throw new IllegalArgumentException("Can not construct SimpleType for a Map (class: "+cls.getName()+")");
}
if (Collection.class.isAssignableFrom(cls)) {
throw new IllegalArgumentException("Can not construct SimpleType for a Collection (class: "+cls.getName()+")");
}
// ... and while we are at it, not array types either
if (cls.isArray()) {
throw new IllegalArgumentException("Can not construct SimpleType for an array (class: "+cls.getName()+")");
}
return new SimpleType(cls);
}
@Override
public SimpleType withTypeHandler(Object h)
{
return new SimpleType(_class, _typeNames, _typeParameters, _valueHandler, h, _asStatic, _typeParametersFor);
}
@Override
public JavaType withContentTypeHandler(Object h) {
// no content type, so:
throw new IllegalArgumentException("Simple types have no content types; can not call withContenTypeHandler()");
}
@Override
public SimpleType withValueHandler(Object h) {
if (h == _valueHandler) {
return this;
}
return new SimpleType(_class, _typeNames, _typeParameters, h, _typeHandler, _asStatic, _typeParametersFor);
}
@Override
public SimpleType withContentValueHandler(Object h) {
// no content type, so:
throw new IllegalArgumentException("Simple types have no content types; can not call withContenValueHandler()");
}
@Override
public SimpleType withStaticTyping() {
return _asStatic ? this : new SimpleType(_class,
_
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>typeNames, _typeParameters, _valueHandler, _typeHandler, _asStatic, _typeParametersFor);
}
@Override
protected String buildCanonicalName()
{
StringBuilder sb = new StringBuilder();
sb.append(_class.getName());
if (_typeParameters != null && _typeParameters.length > 0) {
sb.append('<');
boolean first = true;
for (JavaType t : _typeParameters) {
if (first) {
first = false;
} else {
sb.append(',');
}
sb.append(t.toCanonical());
}
sb.append('>');
}
return sb.toString();
}
/*
/**********************************************************
/* Public API
/**********************************************************
*/
@Override
public boolean isContainerType() { return false; }
@Override
public int containedTypeCount() {
return (_typeParameters == null) ? 0 : _typeParameters.length;
}
@Override
public JavaType containedType(int index)
{
if (index < 0 || _typeParameters == null || index >= _typeParameters.length) {
return null;
}
return _typeParameters[index];
}
@Override
public String containedTypeName(int index)
{
if (index < 0 || _typeNames == null || index >= _typeNames.length) {
return null;
}
return _typeNames[index];
}
@Override
public Class<?> getParameterSource() {
return _typeParametersFor;
}
@Override
public StringBuilder getErasedSignature(StringBuilder sb) {
return _classSignature(_class, sb, true);
}
@Override
public StringBuilder getGenericSignature(StringBuilder sb)
{
_classSignature(_class, sb, false);
if (_typeParameters != null) {
sb.append('<');
for (JavaType param : _typeParameters) {
sb = param.getGenericSignature(sb);
}
sb.append('>');
}
sb.append(';');
return sb;
}
/*
/**********************************************************
/* Standard methods
/**********************************************************
*/
@Override
public String toString()
{
StringBuilder sb = new StringBuilder(40);
sb.append("[simple type, class ").append(buildCanonicalName()).append(']');
return sb.toString();
}
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != getClass()) return false;
SimpleType other = (SimpleType) o;
// Classes must be identical...
if (other._class != this._class) return false;
// And finally, generic bindings,
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.util;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
/**
* Helper class that contains functionality needed by both serialization
* and deserialization side.
*/
public class BeanUtil
{
/*
/**********************************************************
/* Handling property names
/**********************************************************
*/
/**
* @since 2.5
*/
public static String okNameForGetter(AnnotatedMethod am, boolean stdNaming) {
String name = am.getName();
String str = okNameForIsGetter(am, name, stdNaming);
if (str == null) {
str = okNameForRegularGetter(am, name, stdNaming);
}
return str;
}
/**
* @since 2.5
*/
public static String okNameForRegularGetter(AnnotatedMethod am, String name,
boolean stdNaming)
{
if (name.startsWith("get")) {
/* 16-Feb-2009, tatu: To handle [JACKSON-53], need to block
* CGLib-provided method "getCallbacks". Not sure of exact
* safe criteria to get decent coverage without false matches;
* but for now let's assume there's no reason to use any
* such getter from CGLib.
* But let's try this approach...
*/
if ("getCallbacks".equals(name)) {
if (isCglibGetCallbacks(am)) {
return null;
}
} else if ("getMetaClass".equals(name)) {
// 30-Apr-2009, tatu: Need to suppress serialization of a cyclic reference
if (isGroovyMetaClassGetter(am)) {
return null;
}
}
return stdNaming
? stdManglePropertyName(name, 3)
: legacyManglePropertyName(name, 3);
}
return null;
}
/**
* @since 2.5
*/
public static String okNameForIsGetter(AnnotatedMethod am, String name,
boolean stdNaming)
{
if (name.startsWith("is")) { // plus, must return a boolean
Class<?> rt = am.getRawType();
if (rt == Boolean.class || rt == Boolean.TYPE) {
return stdNaming
? stdManglePropertyName(name, 2)
: legacyManglePropertyName(name, 2);
}
}
return null;
}
/**
* @since 2.5
*/
public static String okNameForSetter(AnnotatedMethod am, boolean stdNaming) {
String name = okNameForMutator(am, "set", stdNaming);
if ((name != null)
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
// 26-Nov-2009, tatu: need to suppress this internal groovy method
&& (!"metaClass".equals(name) || !isGroovyMetaClassSetter(am))) {
return name;
}
return null;
}
/**
* @since 2.5
*/
public static String okNameForMutator(AnnotatedMethod am, String prefix,
boolean stdNaming) {
String name = am.getName();
if (name.startsWith(prefix)) {
return stdNaming
? stdManglePropertyName(name, prefix.length())
: legacyManglePropertyName(name, prefix.length());
}
return null;
}
/*
/**********************************************************
/* Handling property names, deprecated methods
/**********************************************************
*/
@Deprecated // since 2.5
public static String okNameForGetter(AnnotatedMethod am) {
return okNameForGetter(am, false);
}
@Deprecated // since 2.5
public static String okNameForRegularGetter(AnnotatedMethod am, String name) {
return okNameForRegularGetter(am, name, false);
}
@Deprecated // since 2.5
public static String okNameForIsGetter(AnnotatedMethod am, String name) {
return okNameForIsGetter(am, name, false);
}
@Deprecated // since 2.5
public static String okNameForSetter(AnnotatedMethod am) {
return okNameForSetter(am, false);
}
@Deprecated // since 2.5
public static String okNameForMutator(AnnotatedMethod am, String prefix) {
return okNameForMutator(am, prefix, false);
}
/*
/**********************************************************
/* Special case handling
/**********************************************************
*/
/**
* This method was added to address [JACKSON-53]: need to weed out
* CGLib-injected "getCallbacks".
* At this point caller has detected a potential getter method
* with name "getCallbacks" and we need to determine if it is
* indeed injectect by Cglib. We do this by verifying that the
* result type is "net.sf.cglib.proxy.Callback[]"
*/
protected static boolean isCglibGetCallbacks(AnnotatedMethod am)
{
Class<?> rt = am.getRawType();
// Ok, first: must return an array type
if (rt == null || !rt.isArray()) {
return false;
}
/* And that type needs to be "net.sf.cglib.proxy.Callback".
* Theoretically could just be a type that implements it, but
* for now let's keep things simple, fix if need be.
*/
Class<?> compType =
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> rt.getComponentType();
// Actually, let's just verify it's a "net.sf.cglib.*" class/interface
Package pkg = compType.getPackage();
if (pkg != null) {
String pname = pkg.getName();
if (pname.contains(".cglib")) {
if (pname.startsWith("net.sf.cglib")
// also, as per [JACKSON-177]
|| pname.startsWith("org.hibernate.repackage.cglib")
// and [core#674]
|| pname.startsWith("org.springframework.cglib")
) {
return true;
}
}
}
return false;
}
/**
* Similar to {@link #isCglibGetCallbacks}, need to suppress
* a cyclic reference to resolve [JACKSON-103]
*/
protected static boolean isGroovyMetaClassSetter(AnnotatedMethod am)
{
Class<?> argType = am.getRawParameterType(0);
Package pkg = argType.getPackage();
if (pkg != null && pkg.getName().startsWith("groovy.lang")) {
return true;
}
return false;
}
/**
* Another helper method to deal with rest of [JACKSON-103]
*/
protected static boolean isGroovyMetaClassGetter(AnnotatedMethod am)
{
Class<?> rt = am.getRawType();
if (rt == null || rt.isArray()) {
return false;
}
Package pkg = rt.getPackage();
if (pkg != null && pkg.getName().startsWith("groovy.lang")) {
return true;
}
return false;
}
/*
/**********************************************************
/* Actual name mangling methods
/**********************************************************
*/
/**
* Method called to figure out name of the property, given
* corresponding suggested name based on a method or field name.
*
* @param basename Name of accessor/mutator method, not including prefix
* ("get"/"is"/"set")
*/
protected static String legacyManglePropertyName(final String basename, final int offset)
{
final int end = basename.length();
if (end == offset) { // empty name, nope
return null;
}
// otherwise, lower case initial chars
StringBuilder sb = null;
for (int i = offset; i < end; ++i) {
char upper = basename.charAt(i);
char lower = Character.toLowerCase(upper);
if (upper == lower) {
break;
}
if (sb == null) {
int l = end-offset;
sb = new StringBuilder(l);
sb.append(basename, offset, end);
}
sb.setCharAt(i
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
+_anySetters.get(1)+")");
}
return _anySetters.getFirst();
}
return null;
}
/**
* Accessor for set of properties that are explicitly marked to be ignored
* via per-property markers (but NOT class annotations).
*/
public Set<String> getIgnoredPropertyNames() {
return _ignoredPropertyNames;
}
/**
* Accessor to find out whether type specified requires inclusion
* of Object Identifier.
*/
public ObjectIdInfo getObjectIdInfo()
{
if (_annotationIntrospector == null) {
return null;
}
ObjectIdInfo info = _annotationIntrospector.findObjectIdInfo(_classDef);
if (info != null) { // 2.1: may also have different defaults for refs:
info = _annotationIntrospector.findObjectReferenceInfo(_classDef, info);
}
return info;
}
/**
* Method for finding Class to use as POJO builder, if any.
*/
public Class<?> findPOJOBuilderClass()
{
return _annotationIntrospector.findPOJOBuilder(_classDef);
}
// for unit tests:
protected Map<String, POJOPropertyBuilder> getPropertyMap() {
return _properties;
}
/*
/**********************************************************
/* Public API: main-level collection
/**********************************************************
*/
/**
* Method that orchestrates collection activities, and needs to be called
* after creating the instance.
*/
public POJOPropertiesCollector collect()
{
_properties.clear();
// First: gather basic data
_addFields();
_addMethods();
_addCreators();
_addInjectables();
// Remove ignored properties, individual entries
_removeUnwantedProperties();
// Rename remaining properties
_renameProperties();
// And use custom naming strategy, if applicable...
PropertyNamingStrategy naming = _findNamingStrategy();
if (naming != null) {
_renameUsing(naming);
}
/* Sort by visibility (explicit over implicit); drop all but first
* of member type (getter, setter etc) if there is visibility
* difference
*/
for (POJOPropertyBuilder property : _properties.values()) {
property.trimByVisibility();
}
// and then "merge" annotations
for (POJOPropertyBuilder property : _properties.values()) {
property.mergeAnnotations(_forSerialization);
}
/* and, if required, apply wrapper name: note, MUST be done after
* annotations are merged.
*/
if (_config.isEnabled(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME)) {
_renameWithWrappers();
}
// well, almost last: there's still ordering...
_sortProperties();
return
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>NamingStrategy(_classDef);
if (namingDef == null) {
return _config.getPropertyNamingStrategy();
}
if (namingDef instanceof PropertyNamingStrategy) {
return (PropertyNamingStrategy) namingDef;
}
/* Alas, there's no way to force return type of "either class
* X or Y" -- need to throw an exception after the fact
*/
if (!(namingDef instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector returned PropertyNamingStrategy definition of type "
+namingDef.getClass().getName()+"; expected type PropertyNamingStrategy or Class<PropertyNamingStrategy> instead");
}
Class<?> namingClass = (Class<?>)namingDef;
if (!PropertyNamingStrategy.class.isAssignableFrom(namingClass)) {
throw new IllegalStateException("AnnotationIntrospector returned Class "
+namingClass.getName()+"; expected Class<PropertyNamingStrategy>");
}
HandlerInstantiator hi = _config.getHandlerInstantiator();
if (hi != null) {
PropertyNamingStrategy pns = hi.namingStrategyInstance(_config, _classDef, namingClass);
if (pns != null) {
return pns;
}
}
return (PropertyNamingStrategy) ClassUtil.createInstance(namingClass,
_config.canOverrideAccessModifiers());
}
protected void _updateCreatorProperty(POJOPropertyBuilder prop, List<POJOPropertyBuilder> creatorProperties) {
if (creatorProperties != null) {
for (int i = 0, len = creatorProperties.size(); i < len; ++i) {
if (creatorProperties.get(i).getInternalName().equals(prop.getInternalName())) {
creatorProperties.set(i, prop);
break;
}
}
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.type;
import java.util.Collection;
import com.fasterxml.jackson.databind.JavaType;
/**
* Type that represents things that act similar to {@link java.util.Collection};
* but may or may not be instances of that interface.
* This specifically allows framework to check for configuration and annotation
* settings used for Map types, and pass these to custom handlers that may be more
* familiar with actual type.
*/
public class CollectionLikeType extends TypeBase
{
private static final long serialVersionUID = 4611641304150899138L;
/**
* Type of elements in collection
*/
protected final JavaType _elementType;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
protected CollectionLikeType(Class<?> collT, JavaType elemT,
Object valueHandler, Object typeHandler, boolean asStatic)
{
super(collT, elemT.hashCode(), valueHandler, typeHandler, asStatic);
_elementType = elemT;
}
@Override
protected JavaType _narrow(Class<?> subclass) {
return new CollectionLikeType(subclass, _elementType,
_valueHandler, _typeHandler, _asStatic);
}
@Override
public JavaType narrowContentsBy(Class<?> contentClass)
{
// Can do a quick check first:
if (contentClass == _elementType.getRawClass()) {
return this;
}
return new CollectionLikeType(_class, _elementType.narrowBy(contentClass),
_valueHandler, _typeHandler, _asStatic);
}
@Override
public JavaType widenContentsBy(Class<?> contentClass)
{
// Can do a quick check first:
if (contentClass == _elementType.getRawClass()) {
return this;
}
return new CollectionLikeType(_class, _elementType.widenBy(contentClass),
_valueHandler, _typeHandler, _asStatic);
}
public static CollectionLikeType construct(Class<?> rawType, JavaType elemT)
{
// nominally component types will be just Object.class
return new CollectionLikeType(rawType, elemT, null, null, false);
}
@Override
public CollectionLikeType withTypeHandler(Object h)
{
return new CollectionLikeType(_class, _elementType, _valueHandler, h, _asStatic);
}
@Override
public CollectionLikeType withContentTypeHandler(Object h)
{
return new CollectionLikeType(_class, _elementType.withTypeHandler(h),
_valueHandler, _typeHandler, _asStatic);
}
@Override
public CollectionLikeType withValueHandler(Object h
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>) {
return new CollectionLikeType(_class, _elementType, h, _typeHandler, _asStatic);
}
@Override
public CollectionLikeType withContentValueHandler(Object h) {
return new CollectionLikeType(_class, _elementType.withValueHandler(h),
_valueHandler, _typeHandler, _asStatic);
}
@Override
public CollectionLikeType withStaticTyping() {
if (_asStatic) {
return this;
}
return new CollectionLikeType(_class, _elementType.withStaticTyping(),
_valueHandler, _typeHandler, true);
}
/*
/**********************************************************
/* Public API
/**********************************************************
*/
@Override
public boolean isContainerType() { return true; }
@Override
public boolean isCollectionLikeType() { return true; }
@Override
public JavaType getContentType() { return _elementType; }
@Override
public int containedTypeCount() { return 1; }
@Override
public JavaType containedType(int index) {
return (index == 0) ? _elementType : null;
}
/**
* Not sure if we should count on this, but type names
* for core interfaces use "E" for element type
*/
@Override
public String containedTypeName(int index) {
if (index == 0) return "E";
return null;
}
// TODO: should allow construction of instances that do refer
// to parameterization, since it is NOT Collection
@Override
public Class<?> getParameterSource() {
return null;
}
@Override
public StringBuilder getErasedSignature(StringBuilder sb) {
return _classSignature(_class, sb, true);
}
@Override
public StringBuilder getGenericSignature(StringBuilder sb) {
_classSignature(_class, sb, false);
sb.append('<');
_elementType.getGenericSignature(sb);
sb.append(">;");
return sb;
}
@Override
protected String buildCanonicalName() {
StringBuilder sb = new StringBuilder();
sb.append(_class.getName());
if (_elementType != null) {
sb.append('<');
sb.append(_elementType.toCanonical());
sb.append('>');
}
return sb.toString();
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
/**
* Method that can be used for checking whether this type is a
* "real" Collection type; meaning whether it represents a parameterized
* subtype of {@link java.util.Collection} or just something that acts
* like one.
*/
public boolean isTrueCollectionType() {
return Collection.class.isAssignableFrom(_class);
}
/*
/**********************************************************
/* Standard methods
/**********************************************************
*/
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return _delegate.getAnnotation(acls);
}
@Override public AnnotatedMember getMember() { return _delegate.getMember(); }
/*
/**********************************************************
/* Deserialization methods
/**********************************************************
*/
@Override
public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt, Object bean)
throws IOException
{
JsonToken t = jp.getCurrentToken();
Object value;
if (t == JsonToken.VALUE_NULL) {
value = (_nullProvider == null) ? null : _nullProvider.nullValue(ctxt);
} else if (_valueTypeDeserializer != null) {
value = _valueDeserializer.deserializeWithType(jp, ctxt, _valueTypeDeserializer);
} else { // the usual case
try {
value = _creator.newInstance(bean);
} catch (Exception e) {
ClassUtil.unwrapAndThrowAsIAE(e, "Failed to instantiate class "+_creator.getDeclaringClass().getName()+", problem: "+e.getMessage());
value = null;
}
_valueDeserializer.deserialize(jp, ctxt, value);
}
set(bean, value);
}
@Override
public Object deserializeSetAndReturn(JsonParser jp,
DeserializationContext ctxt, Object instance)
throws IOException
{
return setAndReturn(instance, deserialize(jp, ctxt));
}
@Override
public final void set(Object instance, Object value) throws IOException {
_delegate.set(instance, value);
}
@Override
public Object setAndReturn(Object instance, Object value) throws IOException {
return _delegate.setAndReturn(instance, value);
}
/*
/**********************************************************
/* JDK serialization handling
/**********************************************************
*/
// When reading things back,
Object readResolve() {
return new InnerClassProperty(this, _annotated);
}
Object writeReplace() {
// need to construct a fake instance to support serialization
if (_annotated != null) {
return this;
}
return new InnerClassProperty(this, new AnnotatedConstructor(null, _creator, null, null));
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
*
* @param ci Derived class of ClassIntrospector with overriden behavior
*
* @since 2.2
*/
public void setClassIntrospector(ClassIntrospector ci);
/**
* Method for registering specified {@link AnnotationIntrospector} as the highest
* priority introspector (will be chained with existing introspector(s) which
* will be used as fallbacks for cases this introspector does not handle)
*
* @param ai Annotation introspector to register.
*/
public void insertAnnotationIntrospector(AnnotationIntrospector ai);
/**
* Method for registering specified {@link AnnotationIntrospector} as the lowest
* priority introspector, chained with existing introspector(s) and called
* as fallback for cases not otherwise handled.
*
* @param ai Annotation introspector to register.
*/
public void appendAnnotationIntrospector(AnnotationIntrospector ai);
/**
* Method for registering specified classes as subtypes (of supertype(s)
* they have)
*/
public void registerSubtypes(Class<?>... subtypes);
/**
* Method for registering specified classes as subtypes (of supertype(s)
* they have), using specified type names.
*/
public void registerSubtypes(NamedType... subtypes);
/**
* Method used for defining mix-in annotations to use for augmenting
* specified class or interface.
* All annotations from
* <code>mixinSource</code> are taken to override annotations
* that <code>target</code> (or its supertypes) has.
*<p>
* Note: mix-ins are registered both for serialization and deserialization
* (which can be different internally).
*<p>
* Note: currently only one set of mix-in annotations can be defined for
* a single class; so if multiple modules register mix-ins, highest
* priority one (last one registered) will have priority over other modules.
*
* @param target Class (or interface) whose annotations to effectively override
* @param mixinSource Class (or interface) whose annotations are to
* be "added" to target's annotations, overriding as necessary
*/
public void setMixInAnnotations(Class<?> target, Class<?> mixinSource);
/**
* Add a deserialization problem handler
*
* @param handler The deserialization problem handler
*/
public void addDeserializationProblemHandler(DeserializationProblemHandler handler);
/**
* Method that may be used to override naming strategy that is used
* by {@link ObjectMapper}.
*
* @since 2.3
*/
public void setNamingStrategy(PropertyNamingStrategy naming);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser;
import java.lang.reflect.Type;
import java.util.*;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.annotation.ObjectIdResolver;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.fasterxml.jackson.databind.cfg.DeserializerFactoryConfig;
import com.fasterxml.jackson.databind.deser.impl.*;
import com.fasterxml.jackson.databind.deser.std.ThrowableDeserializer;
import com.fasterxml.jackson.databind.introspect.*;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.util.ArrayBuilders;
import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.SimpleBeanPropertyDefinition;
/**
* Concrete deserializer factory class that adds full Bean deserializer
* construction logic using class introspection.
* Note that factories specifically do not implement any form of caching:
* aside from configuration they are stateless; caching is implemented
* by other components.
*<p>
* Instances of this class are fully immutable as all configuration is
* done by using "fluent factories" (methods that construct new factory
* instances with different configuration, instead of modifying instance).
*/
public class BeanDeserializerFactory
extends BasicDeserializerFactory
implements java.io.Serializable // since 2.1
{
private static final long serialVersionUID = 1;
/**
* Signature of <b>Throwable.initCause</b> method.
*/
private final static Class<?>[] INIT_CAUSE_PARAMS = new Class<?>[] { Throwable.class };
private final static Class<?>[] NO_VIEWS = new Class<?>[0];
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
/**
* Globally shareable thread-safe instance which has no additional custom deserializers
* registered
*/
public final static BeanDeserializerFactory instance = new BeanDeserializerFactory(
new DeserializerFactoryConfig());
public BeanDeserializerFactory(DeserializerFactoryConfig config) {
super(config);
}
/**
* Method used by module registration functionality, to construct a new bean
* deserializer factory
* with different configuration settings.
*/
@Override
public DeserializerFactory withConfig(DeserializerFactoryConfig config)
{
if (_factoryConfig == config) {
return this;
}
/* 22-Nov-2010, tatu: Handling of subtypes is tricky if we do immutable-with-copy-ctor;
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> return buildBeanDeserializer(ctxt, type, beanDesc);
}
@Override
public JsonDeserializer<Object> createBuilderBasedDeserializer(
DeserializationContext ctxt, JavaType valueType, BeanDescription beanDesc,
Class<?> builderClass)
throws JsonMappingException
{
// First: need a BeanDescription for builder class
JavaType builderType = ctxt.constructType(builderClass);
BeanDescription builderDesc = ctxt.getConfig().introspectForBuilder(builderType);
return buildBuilderBasedDeserializer(ctxt, valueType, builderDesc);
}
/**
* Method called by {@link BeanDeserializerFactory} to see if there might be a standard
* deserializer registered for given type.
*/
protected JsonDeserializer<?> findStdDeserializer(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc)
throws JsonMappingException
{
// note: we do NOT check for custom deserializers here, caller has already
// done that
JsonDeserializer<?> deser = findDefaultDeserializer(ctxt, type, beanDesc);
// Also: better ensure these are post-processable?
if (deser != null) {
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
deser = mod.modifyDeserializer(ctxt.getConfig(), beanDesc, deser);
}
}
}
return deser;
}
protected JavaType materializeAbstractType(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc)
throws JsonMappingException
{
final JavaType abstractType = beanDesc.getType();
// [JACKSON-502]: Now it is possible to have multiple resolvers too,
// as they are registered via module interface.
for (AbstractTypeResolver r : _factoryConfig.abstractTypeResolvers()) {
JavaType concrete = r.resolveAbstractType(ctxt.getConfig(), abstractType);
if (concrete != null) {
return concrete;
}
}
return null;
}
/*
/**********************************************************
/* Public construction method beyond DeserializerFactory API:
/* can be called from outside as well as overridden by
/* sub-classes
/**********************************************************
*/
/**
* Method that is to actually build a bean deserializer instance.
* All basic sanity checks have been done to know that what we have
* may be a valid bean type, and that there are no default simple
* deserializers.
*/
@SuppressWarnings("unchecked")
public JsonDeserializer<Object> buildBeanDeserializer(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc)
throws JsonMappingException
{
// First: check what creators we can use, if any
ValueInstantiator valueInstantiator = findValueInstantiator(ctxt, beanDesc);
BeanDeserializer
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>, builder);
JsonPOJOBuilder.Value builderConfig = builderDesc.findPOJOBuilderConfig();
final String buildMethodName = (builderConfig == null) ?
"build" : builderConfig.buildMethodName;
// and lastly, find build method to use:
AnnotatedMethod buildMethod = builderDesc.findMethod(buildMethodName, null);
if (buildMethod != null) { // note: can't yet throw error; may be given build method
if (config.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(buildMethod.getMember());
}
}
builder.setPOJOBuilder(buildMethod, builderConfig);
// this may give us more information...
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
builder = mod.updateBuilder(config, builderDesc, builder);
}
}
JsonDeserializer<?> deserializer = builder.buildBuilderBased(
valueType, buildMethodName);
// [JACKSON-440]: may have modifier(s) that wants to modify or replace serializer we just built:
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
deserializer = mod.modifyDeserializer(config, builderDesc, deserializer);
}
}
return (JsonDeserializer<Object>) deserializer;
}
protected void addObjectIdReader(DeserializationContext ctxt,
BeanDescription beanDesc, BeanDeserializerBuilder builder)
throws JsonMappingException
{
ObjectIdInfo objectIdInfo = beanDesc.getObjectIdInfo();
if (objectIdInfo == null) {
return;
}
Class<?> implClass = objectIdInfo.getGeneratorType();
JavaType idType;
SettableBeanProperty idProp;
ObjectIdGenerator<?> gen;
ObjectIdResolver resolver = ctxt.objectIdResolverInstance(beanDesc.getClassInfo(), objectIdInfo);
// Just one special case: Property-based generator is trickier
if (implClass == ObjectIdGenerators.PropertyGenerator.class) { // most special one, needs extra work
PropertyName propName = objectIdInfo.getPropertyName();
idProp = builder.findProperty(propName);
if (idProp == null) {
throw new IllegalArgumentException("Invalid Object Id definition for "
+beanDesc.getBeanClass().getName()+": can not find property with name '"+propName+"'");
}
idType = idProp.getType();
gen = new PropertyBasedObjectIdGenerator(objectIdInfo.getScope());
} else {
JavaType type = ctxt.constructType(implClass);
idType = ctxt.getTypeFactory().findTypeParameters(type, ObjectIdGenerator.class)[0];
idProp = null;
gen =
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>'s any-setter
// Implicit ones via @JsonIgnore and equivalent?
if (anySetter == null) {
Collection<String> ignored2 = beanDesc.getIgnoredPropertyNames();
if (ignored2 != null) {
for (String propName : ignored2) {
// allow ignoral of similarly named JSON property, but do not force;
// latter means NOT adding this to 'ignored':
builder.addIgnorable(propName);
}
}
}
final boolean useGettersAsSetters = (ctxt.isEnabled(MapperFeature.USE_GETTERS_AS_SETTERS)
&& ctxt.isEnabled(MapperFeature.AUTO_DETECT_GETTERS));
// Ok: let's then filter out property definitions
List<BeanPropertyDefinition> propDefs = filterBeanProps(ctxt,
beanDesc, builder, beanDesc.findProperties(), ignored);
// After which we can let custom code change the set
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
propDefs = mod.updateProperties(ctxt.getConfig(), beanDesc, propDefs);
}
}
// At which point we still have all kinds of properties; not all with mutators:
for (BeanPropertyDefinition propDef : propDefs) {
SettableBeanProperty prop = null;
/* 18-Oct-2013, tatu: Although constructor parameters have highest precedence,
* we need to do linkage (as per [Issue#318]), and so need to start with
* other types, and only then create constructor parameter, if any.
*/
if (propDef.hasSetter()) {
Type propertyType = propDef.getSetter().getGenericParameterType(0);
prop = constructSettableProperty(ctxt, beanDesc, propDef, propertyType);
} else if (propDef.hasField()) {
Type propertyType = propDef.getField().getGenericType();
prop = constructSettableProperty(ctxt, beanDesc, propDef, propertyType);
} else if (useGettersAsSetters && propDef.hasGetter()) {
/* As per [JACKSON-88], may also need to consider getters
* for Map/Collection properties; but with lowest precedence
*/
AnnotatedMethod getter = propDef.getGetter();
// should only consider Collections and Maps, for now?
Class<?> rawPropertyType = getter.getRawType();
if (Collection.class.isAssignableFrom(rawPropertyType)
|| Map.class.isAssignableFrom(rawPropertyType)) {
prop = constructSetterlessProperty(ctxt, beanDesc, propDef);
}
}
// 25-Sep-2014, tatu: No point in
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> finding constructor parameters for abstract types
// (since they are never used anyway)
if (isConcrete && propDef.hasConstructorParameter()) {
/* [JACKSON-700] If property is passed via constructor parameter, we must
* handle things in special way. Not sure what is the most optimal way...
* for now, let's just call a (new) method in builder, which does nothing.
*/
// but let's call a method just to allow custom builders to be aware...
final String name = propDef.getName();
CreatorProperty cprop = null;
if (creatorProps != null) {
for (SettableBeanProperty cp : creatorProps) {
if (name.equals(cp.getName())) {
cprop = (CreatorProperty) cp;
break;
}
}
}
if (cprop == null) {
throw ctxt.mappingException("Could not find creator property with name '"
+name+"' (in class "+beanDesc.getBeanClass().getName()+")");
}
if (prop != null) {
cprop = cprop.withFallbackSetter(prop);
}
prop = cprop;
builder.addCreatorProperty(cprop);
continue;
}
if (prop != null) {
Class<?>[] views = propDef.findViews();
if (views == null) {
// one more twist: if default inclusion disabled, need to force empty set of views
if (!ctxt.isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION)) {
views = NO_VIEWS;
}
}
// one more thing before adding to builder: copy any metadata
prop.setViews(views);
builder.addProperty(prop);
}
}
}
/**
* Helper method called to filter out explicit ignored properties,
* as well as properties that have "ignorable types".
* Note that this will not remove properties that have no
* setters.
*/
protected List<BeanPropertyDefinition> filterBeanProps(DeserializationContext ctxt,
BeanDescription beanDesc, BeanDeserializerBuilder builder,
List<BeanPropertyDefinition> propDefsIn,
Set<String> ignored)
throws JsonMappingException
{
ArrayList<BeanPropertyDefinition> result = new ArrayList<BeanPropertyDefinition>(
Math.max(4, propDefsIn.size()));
HashMap<Class<?>,Boolean> ignoredTypes = new HashMap<Class<?>,Boolean>();
// These are all valid setters, but we do need to introspect bit more
for (BeanPropertyDefinition property : propDefsIn) {
String name = property.getName();
if (ignored.contains(name)) { // explicit ignoral using @JsonIgnoreProperties needs to block entries
continue;
}
if (!property.
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>hasConstructorParameter()) { // never skip constructor params
Class<?> rawPropertyType = null;
if (property.hasSetter()) {
rawPropertyType = property.getSetter().getRawParameterType(0);
} else if (property.hasField()) {
rawPropertyType = property.getField().getRawType();
}
// [JACKSON-429] Some types are declared as ignorable as well
if ((rawPropertyType != null)
&& (isIgnorableType(ctxt.getConfig(), beanDesc, rawPropertyType, ignoredTypes))) {
// important: make ignorable, to avoid errors if value is actually seen
builder.addIgnorable(name);
continue;
}
}
result.add(property);
}
return result;
}
/**
* Method that will find if bean has any managed- or back-reference properties,
* and if so add them to bean, to be linked during resolution phase.
*/
protected void addReferenceProperties(DeserializationContext ctxt,
BeanDescription beanDesc, BeanDeserializerBuilder builder)
throws JsonMappingException
{
// and then back references, not necessarily found as regular properties
Map<String,AnnotatedMember> refs = beanDesc.findBackReferenceProperties();
if (refs != null) {
for (Map.Entry<String, AnnotatedMember> en : refs.entrySet()) {
String name = en.getKey();
AnnotatedMember m = en.getValue();
Type genericType;
if (m instanceof AnnotatedMethod) {
genericType = ((AnnotatedMethod) m).getGenericParameterType(0);
} else {
genericType = m.getRawType();
}
SimpleBeanPropertyDefinition propDef = SimpleBeanPropertyDefinition.construct(
ctxt.getConfig(), m);
builder.addBackReferenceProperty(name, constructSettableProperty(
ctxt, beanDesc, propDef, genericType));
}
}
}
/**
* Method called locate all members used for value injection (if any),
* constructor {@link com.fasterxml.jackson.databind.deser.impl.ValueInjector} instances, and add them to builder.
*/
protected void addInjectables(DeserializationContext ctxt,
BeanDescription beanDesc, BeanDeserializerBuilder builder)
throws JsonMappingException
{
Map<Object, AnnotatedMember> raw = beanDesc.findInjectables();
if (raw != null) {
boolean fixAccess = ctxt.canOverrideAccessModifiers();
for (Map.Entry<Object, AnnotatedMember> entry : raw.entrySet()) {
AnnotatedMember m = entry.getValue();
if (fixAccess) {
m.fixAccess(); // to ensure we can call it
}
builder.addInjectable(new PropertyName(m.getName()),
beanDesc.resolveType(m.get
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>tableBeanProperty prop = new SetterlessProperty(propDef, type, typeDeser,
beanDesc.getClassAnnotations(), getter);
if (propDeser != null) {
prop = prop.withValueDeserializer(propDeser);
}
return prop;
}
/*
/**********************************************************
/* Helper methods for Bean deserializer, other
/**********************************************************
*/
/**
* Helper method used to skip processing for types that we know
* can not be (i.e. are never consider to be) beans:
* things like primitives, Arrays, Enums, and proxy types.
*<p>
* Note that usually we shouldn't really be getting these sort of
* types anyway; but better safe than sorry.
*/
protected boolean isPotentialBeanType(Class<?> type)
{
String typeStr = ClassUtil.canBeABeanType(type);
if (typeStr != null) {
throw new IllegalArgumentException("Can not deserialize Class "+type.getName()+" (of type "+typeStr+") as a Bean");
}
if (ClassUtil.isProxyType(type)) {
throw new IllegalArgumentException("Can not deserialize Proxy class "+type.getName()+" as a Bean");
}
/* also: can't deserialize some local classes: static are ok; in-method not;
* and with [JACKSON-594], other non-static inner classes are ok
*/
typeStr = ClassUtil.isLocalType(type, true);
if (typeStr != null) {
throw new IllegalArgumentException("Can not deserialize Class "+type.getName()+" (of type "+typeStr+") as a Bean");
}
return true;
}
/**
* Helper method that will check whether given raw type is marked as always ignorable
* (for purpose of ignoring properties with type)
*/
protected boolean isIgnorableType(DeserializationConfig config, BeanDescription beanDesc,
Class<?> type, Map<Class<?>,Boolean> ignoredTypes)
{
Boolean status = ignoredTypes.get(type);
if (status != null) {
return status.booleanValue();
}
BeanDescription desc = config.introspectClassAnnotations(type);
status = config.getAnnotationIntrospector().isIgnorableType(desc.getClassInfo());
// We default to 'false', i.e. not ignorable
return (status == null) ? false : status.booleanValue();
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.concurrent.atomic.AtomicReference;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializable;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsonschema.JsonSerializableSchema;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.type.TypeFactory;
/**
* Generic handler for types that implement {@link JsonSerializable}.
*<p>
* Note: given that this is used for anything that implements
* interface, can not be checked for direct class equivalence.
*/
@JacksonStdImpl
@SuppressWarnings("serial")
public class SerializableSerializer
extends StdSerializer<JsonSerializable>
{
public final static SerializableSerializer instance = new SerializableSerializer();
// Ugh. Should NOT need this...
private final static AtomicReference<ObjectMapper> _mapperReference = new AtomicReference<ObjectMapper>();
protected SerializableSerializer() { super(JsonSerializable.class); }
@Override
public void serialize(JsonSerializable value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
value.serialize(jgen, provider);
}
@Override
public final void serializeWithType(JsonSerializable value, JsonGenerator jgen, SerializerProvider provider,
TypeSerializer typeSer) throws IOException {
value.serializeWithType(jgen, provider, typeSer);
}
@Override
@SuppressWarnings("deprecation")
public JsonNode getSchema(SerializerProvider provider, Type typeHint)
throws JsonMappingException
{
ObjectNode objectNode = createObjectNode();
String schemaType = "any";
String objectProperties = null;
String itemDefinition = null;
if (typeHint != null) {
Class<?> rawClass = TypeFactory.rawClass(typeHint);
if (rawClass.isAnnotationPresent(JsonSerializableSchema.class)) {
JsonSerializableSchema schemaInfo = rawClass.getAnnotation(JsonSerializableSchema.class);
schemaType = schemaInfo.schemaType();
if (!JsonSerializableSchema.NO_VALUE.equals(schemaInfo.schemaObjectPropertiesDefinition())) {
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> Extended API: methods that ObjectMapper will call
/**********************************************************
*/
/**
* Overridable method, used to create a non-blueprint instances from the blueprint.
* This is needed to retain state during serialization.
*/
public abstract DefaultSerializerProvider createInstance(SerializationConfig config,
SerializerFactory jsf);
/**
* The method to be called by {@link ObjectMapper} and {@link ObjectWriter}
* for serializing given value, using serializers that
* this provider has access to (via caching and/or creating new serializers
* as need be).
*/
public void serializeValue(JsonGenerator gen, Object value) throws IOException
{
if (value == null) {
_serializeNull(gen);
return;
}
Class<?> cls = value.getClass();
// true, since we do want to cache root-level typed serializers (ditto for null property)
final JsonSerializer<Object> ser = findTypedValueSerializer(cls, true, null);
// Ok: should we wrap result in an additional property ("root name")?
final boolean wrap;
String rootName = _config.getRootName();
if (rootName == null) { // not explicitly specified
// [JACKSON-163]
wrap = _config.isEnabled(SerializationFeature.WRAP_ROOT_VALUE);
if (wrap) {
PropertyName pname = _rootNames.findRootName(value.getClass(), _config);
gen.writeStartObject();
gen.writeFieldName(pname.simpleAsEncoded(_config));
}
} else if (rootName.length() == 0) {
wrap = false;
} else { // [JACKSON-764]
// empty String means explicitly disabled; non-empty that it is enabled
wrap = true;
gen.writeStartObject();
gen.writeFieldName(rootName);
}
try {
ser.serialize(value, gen, this);
if (wrap) {
gen.writeEndObject();
}
} catch (IOException ioe) { // As per [JACKSON-99], pass IOException and subtypes as-is
throw ioe;
} catch (Exception e) { // but wrap RuntimeExceptions, to get path information
String msg = e.getMessage();
if (msg == null) {
msg = "[no message for "+e.getClass().getName()+"]";
}
throw new JsonMappingException(msg, e);
}
}
/**
* The method to be called by {@link ObjectMapper} and {@link ObjectWriter}
* for serializing given value (assumed to be of specified root type,
* instead of runtime type of value),
* using serializers that
* this provider has access to (via caching and/or creating new serializers
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> rootType, JsonSerializer<Object> ser) throws IOException
{
if (value == null) {
_serializeNull(gen);
return;
}
// Let's ensure types are compatible at this point
if ((rootType != null) && !rootType.getRawClass().isAssignableFrom(value.getClass())) {
_reportIncompatibleRootType(value, rootType);
}
// root value, not reached via property:
if (ser == null) {
ser = findTypedValueSerializer(rootType, true, null);
}
// Ok: should we wrap result in an additional property ("root name")?
final boolean wrap;
String rootName = _config.getRootName();
if (rootName == null) { // not explicitly specified
// [JACKSON-163]
wrap = _config.isEnabled(SerializationFeature.WRAP_ROOT_VALUE);
if (wrap) {
gen.writeStartObject();
PropertyName pname = (rootType == null)
? _rootNames.findRootName(value.getClass(), _config)
: _rootNames.findRootName(rootType, _config);
gen.writeFieldName(pname.simpleAsEncoded(_config));
}
} else if (rootName.length() == 0) {
wrap = false;
} else { // [JACKSON-764]
// empty String means explicitly disabled; non-empty that it is enabled
wrap = true;
gen.writeStartObject();
gen.writeFieldName(rootName);
}
try {
ser.serialize(value, gen, this);
if (wrap) {
gen.writeEndObject();
}
} catch (IOException ioe) { // no wrapping for IO (and derived)
throw ioe;
} catch (Exception e) { // but others do need to be, to get path etc
String msg = e.getMessage();
if (msg == null) {
msg = "[no message for "+e.getClass().getName()+"]";
}
throw new JsonMappingException(msg, e);
}
}
/**
* Alternate serialization call used for polymorphic types, when {@link TypeSerializer}
* is already known, but not actual value serializer.
*
* @since 2.5
*/
public void serializePolymorphic(JsonGenerator gen, Object value, TypeSerializer typeSer)
throws IOException
{
if (value == null) {
_serializeNull(gen);
return;
}
final Class<?> type = value.getClass();
JsonSerializer<Object> ser = findValueSerializer(type, null);
final boolean wrap;
String rootName = _config.getRootName();
if (rootName == null) {
wrap = _config.
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>isEnabled(SerializationFeature.WRAP_ROOT_VALUE);
if (wrap) {
gen.writeStartObject();
PropertyName pname = _rootNames.findRootName(type, _config);
gen.writeFieldName(pname.simpleAsEncoded(_config));
}
} else if (rootName.length() == 0) {
wrap = false;
} else {
wrap = true;
gen.writeStartObject();
gen.writeFieldName(rootName);
}
try {
ser.serializeWithType(value, gen, this, typeSer);
if (wrap) {
gen.writeEndObject();
}
} catch (IOException ioe) { // no wrapping for IO (and derived)
throw ioe;
} catch (Exception e) { // but others do need to be, to get path etc
String msg = e.getMessage();
if (msg == null) {
msg = "[no message for "+e.getClass().getName()+"]";
}
throw new JsonMappingException(msg, e);
}
}
/**
* Helper method called when root value to serialize is null
*
* @since 2.3
*/
protected void _serializeNull(JsonGenerator gen) throws IOException
{
JsonSerializer<Object> ser = getDefaultNullValueSerializer();
try {
ser.serialize(null, gen, this);
} catch (IOException ioe) { // no wrapping for IO (and derived)
throw ioe;
} catch (Exception e) { // but others do need to be, to get path etc
String msg = e.getMessage();
if (msg == null) {
msg = "[no message for "+e.getClass().getName()+"]";
}
throw new JsonMappingException(msg, e);
}
}
/**
* The method to be called by {@link ObjectMapper} and {@link ObjectWriter}
* to generate <a href="http://json-schema.org/">JSON schema</a> for
* given type.
*
* @param type The type for which to generate schema
*/
@SuppressWarnings("deprecation")
public com.fasterxml.jackson.databind.jsonschema.JsonSchema generateJsonSchema(Class<?> type)
throws JsonMappingException
{
if (type == null) {
throw new IllegalArgumentException("A class must be provided");
}
/* no need for embedded type information for JSON schema generation (all
* type information it needs is accessible via "untyped" serializer)
*/
JsonSerializer<Object> ser = findValueSerializer(type, null);
JsonNode schemaNode = (ser instanceof SchemaAware) ?
((SchemaAware) ser).getSchema(this, null) : com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode();
if (!(
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>schemaNode instanceof ObjectNode)) {
throw new IllegalArgumentException("Class " + type.getName()
+" would not be serialized as a JSON object and therefore has no schema");
}
return new com.fasterxml.jackson.databind.jsonschema.JsonSchema((ObjectNode) schemaNode);
}
/**
* The method to be called by {@link ObjectMapper} and {@link ObjectWriter}
* to to expose the format of the given to to the given visitor
*
* @param javaType The type for which to generate format
* @param visitor the visitor to accept the format
*/
public void acceptJsonFormatVisitor(JavaType javaType, JsonFormatVisitorWrapper visitor)
throws JsonMappingException
{
if (javaType == null) {
throw new IllegalArgumentException("A class must be provided");
}
/* no need for embedded type information for JSON schema generation (all
* type information it needs is accessible via "untyped" serializer)
*/
visitor.setProvider(this);
findValueSerializer(javaType, null).acceptJsonFormatVisitor(visitor, javaType);
}
/**
* Method that can be called to see if this serializer provider
* can find a serializer for an instance of given class.
*<p>
* Note that no Exceptions are thrown, including unchecked ones:
* implementations are to swallow exceptions if necessary.
*/
public boolean hasSerializerFor(Class<?> cls, AtomicReference<Throwable> cause)
{
try {
JsonSerializer<?> ser = _findExplicitUntypedSerializer(cls);
return (ser != null);
} catch (JsonMappingException e) {
if (cause != null) {
cause.set(e);
}
} catch (RuntimeException e) {
if (cause == null) { // earlier behavior
throw e;
}
cause.set(e);
}
return false;
}
/*
/********************************************************
/* Access to caching details
/********************************************************
*/
/**
* Method that can be used to determine how many serializers this
* provider is caching currently
* (if it does caching: default implementation does)
* Exact count depends on what kind of serializers get cached;
* default implementation caches all serializers, including ones that
* are eagerly constructed (for optimal access speed)
*<p>
* The main use case for this method is to allow conditional flushing of
* serializer cache, if certain number of entries is reached.
*/
public int cachedSerializersCount() {
return _serializerCache.size();
}
/**
* Method that will drop all serializers currently cached by this provider.
* This can be used to remove memory usage (in case some serializers are
* only used once or so), or to force re-construction of serializers after
* configuration changes for mapper than owns
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> the provider.
*/
public void flushCachedSerializers() {
_serializerCache.flush();
}
/*
/**********************************************************
/* Object Id handling
/**********************************************************
*/
@Override
public WritableObjectId findObjectId(Object forPojo, ObjectIdGenerator<?> generatorType)
{
if (_seenObjectIds == null) {
_seenObjectIds = _createObjectIdMap();
} else {
WritableObjectId oid = _seenObjectIds.get(forPojo);
if (oid != null) {
return oid;
}
}
// Not seen yet; must add an entry, return it. For that, we need generator
ObjectIdGenerator<?> generator = null;
if (_objectIdGenerators == null) {
_objectIdGenerators = new ArrayList<ObjectIdGenerator<?>>(8);
} else {
for (int i = 0, len = _objectIdGenerators.size(); i < len; ++i) {
ObjectIdGenerator<?> gen = _objectIdGenerators.get(i);
if (gen.canUseFor(generatorType)) {
generator = gen;
break;
}
}
}
if (generator == null) {
generator = generatorType.newForSerialization(this);
_objectIdGenerators.add(generator);
}
WritableObjectId oid = new WritableObjectId(generator);
_seenObjectIds.put(forPojo, oid);
return oid;
}
/**
* Overridable helper method used for creating {@link java.util.Map}
* used for storing mappings from serializable objects to their
* Object Ids.
*
* @since 2.3
*/
protected Map<Object,WritableObjectId> _createObjectIdMap()
{
/* 06-Aug-2013, tatu: We may actually want to use equality,
* instead of identity... so:
*/
if (isEnabled(SerializationFeature.USE_EQUALITY_FOR_OBJECT_ID)) {
return new HashMap<Object,WritableObjectId>();
}
return new IdentityHashMap<Object,WritableObjectId>();
}
/*
/**********************************************************
/* Factory method impls
/**********************************************************
*/
@Override
public JsonSerializer<Object> serializerInstance(Annotated annotated, Object serDef) throws JsonMappingException
{
if (serDef == null) {
return null;
}
JsonSerializer<?> ser;
if (serDef instanceof JsonSerializer) {
ser = (JsonSerializer<?>) serDef;
} else {
/* Alas, there's no way to force return type of "either class
* X or Y" -- need to throw an exception after the fact
*/
if (!(serDef instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector returned serializer definition of type "
+ser
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Def.getClass().getName()+"; expected type JsonSerializer or Class<JsonSerializer> instead");
}
Class<?> serClass = (Class<?>)serDef;
// there are some known "no class" markers to consider too:
if (serClass == JsonSerializer.None.class || ClassUtil.isBogusClass(serClass)) {
return null;
}
if (!JsonSerializer.class.isAssignableFrom(serClass)) {
throw new IllegalStateException("AnnotationIntrospector returned Class "
+serClass.getName()+"; expected Class<JsonSerializer>");
}
HandlerInstantiator hi = _config.getHandlerInstantiator();
ser = (hi == null) ? null : hi.serializerInstance(_config, annotated, serClass);
if (ser == null) {
ser = (JsonSerializer<?>) ClassUtil.createInstance(serClass,
_config.canOverrideAccessModifiers());
}
}
return (JsonSerializer<Object>) _handleResolvable(ser);
}
/*
/**********************************************************
/* Helper classes
/**********************************************************
*/
/**
* Concrete implementation that defines factory method(s),
* defined as final.
*/
public final static class Impl extends DefaultSerializerProvider {
private static final long serialVersionUID = 1L;
public Impl() { super(); }
public Impl(Impl src) { super(src); }
protected Impl(SerializerProvider src, SerializationConfig config,SerializerFactory f) {
super(src, config, f);
}
@Override
public DefaultSerializerProvider copy()
{
if (getClass() != Impl.class) {
return super.copy();
}
return new Impl(this);
}
@Override
public Impl createInstance(SerializationConfig config, SerializerFactory jsf) {
return new Impl(this, config, jsf);
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.*;
/**
* Intermediate base class for serializers used for various
* Java arrays.
*
* @param <T> Type of arrays serializer handles
*/
@SuppressWarnings("serial")
public abstract class ArraySerializerBase<T>
extends ContainerSerializer<T>
{
protected final BeanProperty _property;
protected ArraySerializerBase(Class<T> cls)
{
super(cls);
_property = null;
}
protected ArraySerializerBase(Class<T> cls, BeanProperty property)
{
super(cls);
_property = property;
}
protected ArraySerializerBase(ArraySerializerBase<?> src)
{
super(src._handledType, false);
_property = src._property;
}
protected ArraySerializerBase(ArraySerializerBase<?> src, BeanProperty property)
{
super(src._handledType, false);
_property = property;
}
// NOTE: as of 2.5, sub-classes SHOULD override (in 2.4 and before, was final),
// at least if they can provide access to actual size of value and use `writeStartArray()`
// variant that passes size of array to output, which is helpful with some data formats
@Override
public void serialize(T value, JsonGenerator gen, SerializerProvider provider) throws IOException
{
if (provider.isEnabled(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED)
&& hasSingleElement(value)) {
serializeContents(value, gen, provider);
return;
}
gen.writeStartArray();
// [databind#631]: Assign current value, to be accessible by custom serializers
gen.setCurrentValue(value);
serializeContents(value, gen, provider);
gen.writeEndArray();
}
@Override
public final void serializeWithType(T value, JsonGenerator gen, SerializerProvider provider,
TypeSerializer typeSer)
throws IOException
{
// note: let's NOT consider [JACKSON-805] here; gets too complicated, and probably just won't work
typeSer.writeTypePrefixForArray(value, gen);
// [databind#631]: Assign current value, to be accessible by custom serializers
gen.setCurrentValue(value);
serializeContents(value, gen, provider);
typeSer.writeTypeSuffixForArray(value, gen);
}
protected abstract void serializeContents(T value, JsonGenerator jgen, SerializerProvider
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> "static T valueOf(String)" (or equivalent marked
* with @JsonCreator annotation?)
*/
Method m = beanDesc.findFactoryMethod(String.class);
if (m != null){
if (config.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(m);
}
return new StdKeyDeserializer.StringFactoryKeyDeserializer(m);
}
// nope, no such luck...
return null;
}
/*
/**********************************************************
/* KeyDeserializers implementation
/**********************************************************
*/
@Override
public KeyDeserializer findKeyDeserializer(JavaType type,
DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException
{
Class<?> raw = type.getRawClass();
// 23-Apr-2013, tatu: Map primitive types, just in case one was given
if (raw.isPrimitive()) {
raw = ClassUtil.wrapperType(raw);
}
return StdKeyDeserializer.forType(raw);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
import java.lang.reflect.Type;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.TimeZone;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.jsonFormatVisitors.*;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.util.StdDateFormat;
@SuppressWarnings("serial")
public abstract class DateTimeSerializerBase<T>
extends StdScalarSerializer<T>
implements ContextualSerializer
{
/**
* Flag that indicates that serialization must be done as the
* Java timestamp, regardless of other settings.
*/
protected final Boolean _useTimestamp;
/**
* Specific format to use, if not default format: non null value
* also indicates that serialization is to be done as JSON String,
* not numeric timestamp, unless {@link #_useTimestamp} is true.
*/
protected final DateFormat _customFormat;
protected DateTimeSerializerBase(Class<T> type,
Boolean useTimestamp, DateFormat customFormat)
{
super(type);
_useTimestamp = useTimestamp;
_customFormat = customFormat;
}
public abstract DateTimeSerializerBase<T> withFormat(Boolean timestamp, DateFormat customFormat);
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov,
BeanProperty property) throws JsonMappingException
{
if (property != null) {
JsonFormat.Value format = prov.getAnnotationIntrospector().findFormat((Annotated)property.getMember());
if (format != null) {
// Simple case first: serialize as numeric timestamp?
if (format.getShape().isNumeric()) {
return withFormat(Boolean.TRUE, null);
}
Boolean asNumber = (format.getShape() == JsonFormat.Shape.STRING) ? Boolean.FALSE : null;
// If not, do we have a pattern?
TimeZone tz = format.getTimeZone();
if (format.hasPattern()) {
String pattern = format.getPattern();
final Locale loc = format.hasLocale() ? format.getLocale() : prov.getLocale();
SimpleDateFormat df = new SimpleDateFormat(pattern, loc);
if (tz == null) {
tz = prov.getTimeZone();
}
df.setTimeZone
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.introspect;
import java.lang.reflect.*;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeBindings;
import com.fasterxml.jackson.databind.util.ClassUtil;
public final class AnnotatedMethod
extends AnnotatedWithParams
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
final protected transient Method _method;
// // Simple lazy-caching:
protected Class<?>[] _paramClasses;
/**
* Field that is used to make JDK serialization work with this
* object.
*
* @since 2.1
*/
protected Serialization _serialization;
/*
/*****************************************************
/* Life-cycle
/*****************************************************
*/
public AnnotatedMethod(AnnotatedClass ctxt, Method method,
AnnotationMap classAnn, AnnotationMap[] paramAnnotations)
{
super(ctxt, classAnn, paramAnnotations);
if (method == null) {
throw new IllegalArgumentException("Can not construct AnnotatedMethod with null Method");
}
_method = method;
}
/**
* Method used for JDK serialization support
* @since 2.1
*/
protected AnnotatedMethod(Serialization ser)
{
super(null, null, null);
_method = null;
_serialization = ser;
}
/**
* Method that constructs a new instance with settings (annotations, parameter annotations)
* of this instance, but with different physical {@link Method}.
*/
public AnnotatedMethod withMethod(Method m) {
return new AnnotatedMethod(_context, m, _annotations, _paramAnnotations);
}
@Override
public AnnotatedMethod withAnnotations(AnnotationMap ann) {
return new AnnotatedMethod(_context, _method, ann, _paramAnnotations);
}
/*
/*****************************************************
/* Annotated impl
/*****************************************************
*/
@Override
public Method getAnnotated() { return _method; }
@Override
public int getModifiers() { return _method.getModifiers(); }
@Override
public String getName() { return _method.getName(); }
/**
* For methods, this returns declared return type, which is only
* useful with getters (setters do not return anything; hence "void"
* type is returned here)
*/
@Override
public Type getGenericType() {
return _method.getGenericReturnType();
}
/**
* For methods, this returns declared return type, which is only
* useful with getters (setters do not usually return anything;
* hence "void" type is returned here)
*/
@Override
public Class<?> getRawType() {
return _method.getReturnType();
}
/**
* As
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> per [JACKSON-468], we need to also allow declaration of local
* type bindings; mostly it will allow defining bounds.
*/
@Override
public JavaType getType(TypeBindings bindings) {
return getType(bindings, _method.getTypeParameters());
}
@Override
public final Object call() throws Exception {
return _method.invoke(null);
}
@Override
public final Object call(Object[] args) throws Exception {
return _method.invoke(null, args);
}
@Override
public final Object call1(Object arg) throws Exception {
return _method.invoke(null, arg);
}
/*
/********************************************************
/* AnnotatedMember impl
/********************************************************
*/
@Override
public Class<?> getDeclaringClass() { return _method.getDeclaringClass(); }
@Override
public Method getMember() { return _method; }
@Override
public void setValue(Object pojo, Object value) throws IllegalArgumentException
{
try {
_method.invoke(pojo, value);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException("Failed to setValue() with method "
+getFullName()+": "+e.getMessage(), e);
} catch (InvocationTargetException e) {
throw new IllegalArgumentException("Failed to setValue() with method "
+getFullName()+": "+e.getMessage(), e);
}
}
@Override
public Object getValue(Object pojo) throws IllegalArgumentException
{
try {
return _method.invoke(pojo);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException("Failed to getValue() with method "
+getFullName()+": "+e.getMessage(), e);
} catch (InvocationTargetException e) {
throw new IllegalArgumentException("Failed to getValue() with method "
+getFullName()+": "+e.getMessage(), e);
}
}
/*
/*****************************************************
/* Extended API, generic
/*****************************************************
*/
@Override
public int getParameterCount() {
return getRawParameterTypes().length;
}
public String getFullName() {
return getDeclaringClass().getName() + "#" + getName() + "("
+getParameterCount()+" params)";
}
public Class<?>[] getRawParameterTypes()
{
if (_paramClasses == null) {
_paramClasses = _method.getParameterTypes();
}
return _paramClasses;
}
public Type[] getGenericParameterTypes() {
return _method.getGenericParameterTypes();
}
@Override
public Class<?> getRawParameterType(int index)
{
Class<?>[] types = getRawParameterTypes();
return (index >= types.length) ? null : types[index];
}
@Override
public Type getGenericParameterType(int index)
{
Type[] types = _
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>method.getGenericParameterTypes();
return (index >= types.length) ? null : types[index];
}
public Class<?> getRawReturnType() {
return _method.getReturnType();
}
public Type getGenericReturnType() {
return _method.getGenericReturnType();
}
/**
* Helper method that can be used to check whether method returns
* a value or not; if return type declared as <code>void</code>, returns
* false, otherwise true
*
* @since 2.4
*/
public boolean hasReturnType() {
Class<?> rt = getRawReturnType();
return (rt != Void.TYPE && rt != Void.class);
}
/*
/********************************************************
/* Other
/********************************************************
*/
@Override
public String toString() {
return "[method "+getFullName()+"]";
}
@Override
public int hashCode() {
return _method.getName().hashCode();
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (o == null || o.getClass() != getClass()) return false;
return ((AnnotatedMethod) o)._method == _method;
}
/*
/**********************************************************
/* JDK serialization handling
/**********************************************************
*/
Object writeReplace() {
return new AnnotatedMethod(new Serialization(_method));
}
Object readResolve() {
Class<?> clazz = _serialization.clazz;
try {
Method m = clazz.getDeclaredMethod(_serialization.name,
_serialization.args);
// 06-Oct-2012, tatu: Has "lost" its security override, may need to force back
if (!m.isAccessible()) {
ClassUtil.checkAndFixAccess(m);
}
return new AnnotatedMethod(null, m, null, null);
} catch (Exception e) {
throw new IllegalArgumentException("Could not find method '"+_serialization.name
+"' from Class '"+clazz.getName());
}
}
/**
* Helper class that is used as the workaround to persist
* Field references. It basically just stores declaring class
* and field name.
*/
private final static class Serialization
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
protected Class<?> clazz;
protected String name;
protected Class<?>[] args;
public Serialization(Method setter) {
clazz = setter.getDeclaringClass();
name = setter.getName();
args = setter.getParameterTypes();
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import java.util.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
/**
* Standard deserializer for {@link EnumSet}s.
* <p>
* Note: casting within this class is all messed up -- just could not figure out a way
* to properly deal with recursive definition of "EnumSet<K extends Enum<K>, V>
*/
@SuppressWarnings("rawtypes")
public class EnumSetDeserializer
extends StdDeserializer<EnumSet<?>>
implements ContextualDeserializer
{
private static final long serialVersionUID = 1L; // since 2.5
protected final JavaType _enumType;
protected final Class<Enum> _enumClass;
protected JsonDeserializer<Enum<?>> _enumDeserializer;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
@SuppressWarnings("unchecked" )
public EnumSetDeserializer(JavaType enumType, JsonDeserializer<?> deser)
{
super(EnumSet.class);
_enumType = enumType;
_enumClass = (Class<Enum>) enumType.getRawClass();
_enumDeserializer = (JsonDeserializer<Enum<?>>) deser;
}
public EnumSetDeserializer withDeserializer(JsonDeserializer<?> deser) {
if (_enumDeserializer == deser) {
return this;
}
return new EnumSetDeserializer(_enumType, deser);
}
/**
* Because of costs associated with constructing Enum resolvers,
* let's cache instances by default.
*/
@Override
public boolean isCachable() { return true; }
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
BeanProperty property) throws JsonMappingException
{
JsonDeserializer<?> deser = _enumDeserializer;
if (deser == null) {
deser = ctxt.findContextualValueDeserializer(_enumType, property);
} else { // if directly assigned, probably not yet contextual, so:
deser = ctxt.handleSecondaryContextualization(deser, property, _enumType);
}
return withDeserializer(deser);
}
/*
/**********************************************************
/* JsonDeserializer API
/**********************************************************
*/
@SuppressWarnings("unchecked")
@Override
public EnumSet<?> deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
// Ok: must point to START_ARRAY (or equivalent)
if (!jp.isExpectedStartArrayToken()) {
throw ctxt.mappingException(EnumSet.class);
}
EnumSet
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>.
*/
public @interface Prop
{
/**
* Actual implementation class (a subtype of {@link VirtualBeanPropertyWriter})
* of the property to instantiate (using the no-argument default constructor).
*/
public Class<? extends VirtualBeanPropertyWriter> value();
/**
* Name of the property to possibly use for serializing (although implementation
* may choose to not use this information).
*/
public String name() default "";
/**
* Optional namespace to use along with {@link #name};
* only relevant for data formats that use namespaces (like XML).
*/
public String namespace() default "";
/**
* When to include value of the property. Default value indicates that
* property should only be written if specified attribute has a non-null
* value. As with other properties, actual property implementation may or may
* not choose to use this inclusion information.
*/
public JsonInclude.Include include() default JsonInclude.Include.NON_NULL;
/**
* Metadata about property, similar to
* {@link com.fasterxml.jackson.annotation.JsonProperty#required()}.
*/
public boolean required() default false;
/**
* Nominal type of the property. Passed as type information for related
* virtual objects, and may (or may not be) used by implementation
* for choosing serializer to use.
*/
public Class<?> type() default Object.class;
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser;
import java.util.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.ser.impl.ReadOnlyClassToSerializerMap;
/**
* Simple cache object that allows for doing 2-level lookups: first level is
* by "local" read-only lookup Map (used without locking)
* and second backup level is by a shared modifiable HashMap.
* The idea is that after a while, most serializers are found from the
* local Map (to optimize performance, reduce lock contention),
* but that during buildup we can use a shared map to reduce both
* number of distinct read-only maps constructed, and number of
* serializers constructed.
*<p>
* Since version 1.5 cache will actually contain three kinds of entries,
* based on combination of class pair key. First class in key is for the
* type to serialize, and second one is type used for determining how
* to resolve value type. One (but not both) of entries can be null.
*/
public final class SerializerCache
{
/**
* Shared, modifiable map; all access needs to be through synchronized blocks.
*<p>
* NOTE: keys are of various types (see below for key types), in addition to
* basic {@link JavaType} used for "untyped" serializers.
*/
private HashMap<TypeKey, JsonSerializer<Object>> _sharedMap = new HashMap<TypeKey, JsonSerializer<Object>>(64);
/**
* Most recent read-only instance, created from _sharedMap, if any.
*/
private volatile ReadOnlyClassToSerializerMap _readOnlyMap = null;
public SerializerCache() { }
/**
* Method that can be called to get a read-only instance populated from the
* most recent version of the shared lookup Map.
*/
public ReadOnlyClassToSerializerMap getReadOnlyLookupMap()
{
ReadOnlyClassToSerializerMap m = _readOnlyMap;
if(m == null) {
synchronized (this) {
m = _readOnlyMap;
if (m == null) {
_readOnlyMap = m = ReadOnlyClassToSerializerMap.from(_sharedMap);
}
}
}
return m.instance();
}
/*
/**********************************************************
/* Lookup methods for accessing shared (slow) cache
/**********************************************************
*/
public synchronized int size() {
return _sharedMap.size();
}
/**
* Method that checks if the shared (and hence, synchronized) lookup Map might have
* untyped serializer for given type.
*/
public JsonSerializer<Object> untypedValueSerializer(Class<?> type)
{
synchronized (this) {
return _sharedMap.get(new Type
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Key(type, false));
}
}
public JsonSerializer<Object> untypedValueSerializer(JavaType type)
{
synchronized (this) {
return _sharedMap.get(new TypeKey(type, false));
}
}
public JsonSerializer<Object> typedValueSerializer(JavaType type)
{
synchronized (this) {
return _sharedMap.get(new TypeKey(type, true));
}
}
public JsonSerializer<Object> typedValueSerializer(Class<?> cls)
{
synchronized (this) {
return _sharedMap.get(new TypeKey(cls, true));
}
}
/*
/**********************************************************
/* Methods for adding shared serializer instances
/**********************************************************
*/
/**
* Method called if none of lookups succeeded, and caller had to construct
* a serializer. If so, we will update the shared lookup map so that it
* can be resolved via it next time.
*/
public void addTypedSerializer(JavaType type, JsonSerializer<Object> ser)
{
synchronized (this) {
if (_sharedMap.put(new TypeKey(type, true), ser) == null) {
// let's invalidate the read-only copy, too, to get it updated
_readOnlyMap = null;
}
}
}
public void addTypedSerializer(Class<?> cls, JsonSerializer<Object> ser)
{
synchronized (this) {
if (_sharedMap.put(new TypeKey(cls, true), ser) == null) {
// let's invalidate the read-only copy, too, to get it updated
_readOnlyMap = null;
}
}
}
public void addAndResolveNonTypedSerializer(Class<?> type, JsonSerializer<Object> ser,
SerializerProvider provider)
throws JsonMappingException
{
synchronized (this) {
if (_sharedMap.put(new TypeKey(type, false), ser) == null) {
// let's invalidate the read-only copy, too, to get it updated
_readOnlyMap = null;
}
/* Finally: some serializers want to do post-processing, after
* getting registered (to handle cyclic deps).
*/
/* 14-May-2011, tatu: As per [JACKSON-570], resolving needs to be done
* in synchronized manner; this because while we do need to register
* instance first, we also must keep lock until resolution is complete
*/
if (ser instanceof ResolvableSerializer) {
((ResolvableSerializer) ser).resolve(provider);
}
}
}
public void addAndResolveNonTypedSerializer(JavaType type, JsonSerializer<Object> ser,
SerializerProvider provider)
throws JsonMappingException
{
synchronized (this)
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> {
if (_sharedMap.put(new TypeKey(type, false), ser) == null) {
// let's invalidate the read-only copy, too, to get it updated
_readOnlyMap = null;
}
/* Finally: some serializers want to do post-processing, after
* getting registered (to handle cyclic deps).
*/
/* 14-May-2011, tatu: As per [JACKSON-570], resolving needs to be done
* in synchronized manner; this because while we do need to register
* instance first, we also must keep lock until resolution is complete
*/
if (ser instanceof ResolvableSerializer) {
((ResolvableSerializer) ser).resolve(provider);
}
}
}
/**
* Method called by StdSerializerProvider#flushCachedSerializers() to
* clear all cached serializers
*/
public synchronized void flush() {
_sharedMap.clear();
}
/*
/**************************************************************
/* Helper class(es)
/**************************************************************
*/
/**
* Key that offers two "modes"; one with raw class, as used for
* cases were raw class type is available (for example, when using
* runtime type); and one with full generics-including.
*/
public final static class TypeKey
{
protected int _hashCode;
protected Class<?> _class;
protected JavaType _type;
/**
* Indicator of whether serializer stored has a type serializer
* wrapper around it or not; if not, it is "untyped" serializer;
* if it has, it is "typed"
*/
protected boolean _isTyped;
public TypeKey(Class<?> key, boolean typed) {
_class = key;
_type = null;
_isTyped = typed;
_hashCode = hash(key, typed);
}
public TypeKey(JavaType key, boolean typed) {
_type = key;
_class = null;
_isTyped = typed;
_hashCode = hash(key, typed);
}
private final static int hash(Class<?> cls, boolean typed) {
int hash = cls.getName().hashCode();
if (typed) {
++hash;
}
return hash;
}
private final static int hash(JavaType type, boolean typed) {
int hash = type.hashCode() - 1;
if (typed) {
--hash;
}
return hash;
}
public void resetTyped(Class<?> cls) {
_type = null;
_class = cls;
_isTyped = true;
_hashCode = hash(cls, true);
}
public void resetUntyped(Class<?> cls) {
_type = null;
_class = cls;
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.cfg.SerializerFactoryConfig;
import com.fasterxml.jackson.databind.ext.OptionalHandlerFactory;
import com.fasterxml.jackson.databind.introspect.*;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.impl.*;
import com.fasterxml.jackson.databind.ser.std.*;
import com.fasterxml.jackson.databind.type.*;
import com.fasterxml.jackson.databind.util.*;
/**
* Factory class that can provide serializers for standard JDK classes,
* as well as custom classes that extend standard classes or implement
* one of "well-known" interfaces (such as {@link java.util.Collection}).
*<p>
* Since all the serializers are eagerly instantiated, and there is
* no additional introspection or customizability of these types,
* this factory is essentially stateless.
*/
@SuppressWarnings("serial")
public abstract class BasicSerializerFactory
extends SerializerFactory
implements java.io.Serializable
{
/*
/**********************************************************
/* Configuration, lookup tables/maps
/**********************************************************
*/
/**
* Since these are all JDK classes, we shouldn't have to worry
* about ClassLoader used to load them. Rather, we can just
* use the class name, and keep things simple and efficient.
*/
protected final static HashMap<String, JsonSerializer<?>> _concrete =
new HashMap<String, JsonSerializer<?>>();
/**
* Actually it may not make much sense to eagerly instantiate all
* kinds of serializers: so this Map actually contains class references,
* not instances
*/
protected final static HashMap<String, Class<? extends JsonSerializer<?>>> _concreteLazy =
new HashMap<String, Class<? extends JsonSerializer<?>>>();
static {
/* String and string-like types (note: date types explicitly
* not included -- can use either textual or numeric serialization)
*/
_concrete.put(String.class.getName(), new StringSerializer());
final ToStringSerializer sls = ToStringSerializer
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>.instance;
_concrete.put(StringBuffer.class.getName(), sls);
_concrete.put(StringBuilder.class.getName(), sls);
_concrete.put(Character.class.getName(), sls);
_concrete.put(Character.TYPE.getName(), sls);
// Primitives/wrappers for primitives (primitives needed for Beans)
NumberSerializers.addAll(_concrete);
_concrete.put(Boolean.TYPE.getName(), new BooleanSerializer(true));
_concrete.put(Boolean.class.getName(), new BooleanSerializer(false));
// Other numbers, more complicated
_concrete.put(BigInteger.class.getName(), new NumberSerializer(BigInteger.class));
_concrete.put(BigDecimal.class.getName(),new NumberSerializer(BigDecimal.class));
// Other discrete non-container types:
// First, Date/Time zoo:
_concrete.put(Calendar.class.getName(), CalendarSerializer.instance);
DateSerializer dateSer = DateSerializer.instance;
_concrete.put(java.util.Date.class.getName(), dateSer);
// note: timestamps are very similar to java.util.Date, thus serialized as such
_concrete.put(java.sql.Timestamp.class.getName(), dateSer);
// leave some of less commonly used ones as lazy, no point in proactive construction
_concreteLazy.put(java.sql.Date.class.getName(), SqlDateSerializer.class);
_concreteLazy.put(java.sql.Time.class.getName(), SqlTimeSerializer.class);
// And then other standard non-structured JDK types
for (Map.Entry<Class<?>,Object> en : StdJdkSerializers.all()) {
Object value = en.getValue();
if (value instanceof JsonSerializer<?>) {
_concrete.put(en.getKey().getName(), (JsonSerializer<?>) value);
} else if (value instanceof Class<?>) {
@SuppressWarnings("unchecked")
Class<? extends JsonSerializer<?>> cls = (Class<? extends JsonSerializer<?>>) value;
_concreteLazy.put(en.getKey().getName(), cls);
} else { // should never happen, but:
throw new IllegalStateException("Internal error: unrecognized value of type "+en.getClass().getName());
}
}
// Jackson-specific type(s)
// (Q: can this ever be sub-classed?)
_concreteLazy.put(TokenBuffer.class.getName(), TokenBufferSerializer.class);
}
/*
/**********************************************************
/* Configuration
/**********************************************************
*/
/**
* Configuration settings for this factory; immutable instance (just like this
* factory), new version created via copy-constructor (fluent-style)
*/
protected final SerializerFactoryConfig _factoryConfig;
/*
/
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
JsonSerializer<?> ser = null;
// Minor optimization: to avoid constructing beanDesc, bail out if none registered
if (_factoryConfig.hasKeySerializers()) {
// Only thing we have here are module-provided key serializers:
for (Serializers serializers : _factoryConfig.keySerializers()) {
ser = serializers.findSerializer(config, keyType, beanDesc);
if (ser != null) {
break;
}
}
}
if (ser == null) {
ser = defaultImpl;
if (ser == null) {
ser = StdKeySerializers.getStdKeySerializer(config, keyType.getRawClass(), false);
// As per [databind#47], also need to support @JsonValue
if (ser == null) {
beanDesc = config.introspect(keyType);
AnnotatedMethod am = beanDesc.findJsonValueMethod();
if (am != null) {
final Class<?> rawType = am.getRawReturnType();
JsonSerializer<?> delegate = StdKeySerializers.getStdKeySerializer(config,
rawType, true);
Method m = am.getAnnotated();
if (config.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(m);
}
ser = new JsonValueSerializer(m, delegate);
} else {
ser = StdKeySerializers.getDefault();
}
}
}
}
// [Issue#120]: Allow post-processing
if (_factoryConfig.hasSerializerModifiers()) {
for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
ser = mod.modifyKeySerializer(config, keyType, beanDesc, ser);
}
}
return (JsonSerializer<Object>) ser;
}
/**
* Method called to construct a type serializer for values with given declared
* base type. This is called for values other than those of bean property
* types.
*/
@Override
public TypeSerializer createTypeSerializer(SerializationConfig config,
JavaType baseType)
{
BeanDescription bean = config.introspectClassAnnotations(baseType.getRawClass());
AnnotatedClass ac = bean.getClassInfo();
AnnotationIntrospector ai = config.getAnnotationIntrospector();
TypeResolverBuilder<?> b = ai.findTypeResolver(config, ac, baseType);
/* Ok: if there is no explicit type info handler, we may want to
* use a default. If so, config object knows what to use.
*/
Collection<NamedType> subtypes = null;
if (b == null) {
b = config.getDefaultTyper(baseType);
} else {
subtypes = config.getSubtypeResolver().collectAndResolveSubtypes(ac, config, ai);
}
if (b == null
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>) {
return null;
}
return b.buildTypeSerializer(config, baseType, subtypes);
}
/*
/**********************************************************
/* Additional API for other core classes
/**********************************************************
*/
protected abstract Iterable<Serializers> customSerializers();
/*
/**********************************************************
/* Overridable secondary serializer accessor methods
/**********************************************************
*/
/**
* Method that will use fast lookup (and identity comparison) methods to
* see if we know serializer to use for given type.
*/
protected final JsonSerializer<?> findSerializerByLookup(JavaType type,
SerializationConfig config, BeanDescription beanDesc,
boolean staticTyping)
{
Class<?> raw = type.getRawClass();
String clsName = raw.getName();
JsonSerializer<?> ser = _concrete.get(clsName);
if (ser == null) {
Class<? extends JsonSerializer<?>> serClass = _concreteLazy.get(clsName);
if (serClass != null) {
try {
return serClass.newInstance();
} catch (Exception e) {
throw new IllegalStateException("Failed to instantiate standard serializer (of type "+serClass.getName()+"): "
+e.getMessage(), e);
}
}
}
return ser;
}
/**
* Method called to see if one of primary per-class annotations
* (or related, like implementing of {@link JsonSerializable})
* determines the serializer to use.
*<p>
* Currently handles things like:
*<ul>
* <li>If type implements {@link JsonSerializable}, use that
* </li>
* <li>If type has {@link com.fasterxml.jackson.annotation.JsonValue} annotation (or equivalent), build serializer
* based on that property
* </li>
*</ul>
*
* @since 2.0
*/
protected final JsonSerializer<?> findSerializerByAnnotations(SerializerProvider prov,
JavaType type, BeanDescription beanDesc)
throws JsonMappingException
{
Class<?> raw = type.getRawClass();
// First: JsonSerializable?
if (JsonSerializable.class.isAssignableFrom(raw)) {
return SerializableSerializer.instance;
}
// Second: @JsonValue for any type
AnnotatedMethod valueMethod = beanDesc.findJsonValueMethod();
if (valueMethod != null) {
Method m = valueMethod.getAnnotated();
if (prov.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(m);
}
JsonSerializer<Object> ser = findSerializerFromAnnotation(prov, valueMethod);
return new JsonValueSerializer(m, ser);
}
// No well-known annotations...
return null;
}
/**
* Method for checking if we can determine serializer to use based on set of
* known
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> primary types, checking for set of known base types (exact matches
* having been compared against with <code>findSerializerByLookup</code>).
* This does not include "secondary" interfaces, but
* mostly concrete or abstract base classes.
*/
protected final JsonSerializer<?> findSerializerByPrimaryType(SerializerProvider prov,
JavaType type, BeanDescription beanDesc,
boolean staticTyping)
throws JsonMappingException
{
Class<?> raw = type.getRawClass();
// Then check for optional/external serializers [JACKSON-386]
JsonSerializer<?> ser = findOptionalStdSerializer(prov, type, beanDesc, staticTyping);
if (ser != null) {
return ser;
}
if (Calendar.class.isAssignableFrom(raw)) {
return CalendarSerializer.instance;
}
if (java.util.Date.class.isAssignableFrom(raw)) {
return DateSerializer.instance;
}
if (Map.Entry.class.isAssignableFrom(raw)) {
JavaType kt, vt;
JavaType[] params = prov.getTypeFactory().findTypeParameters(type, Map.Entry.class);
if (params == null || params.length != 2) { // assume that if we don't get 2, they are wrong...
kt = vt = TypeFactory.unknownType();
} else {
kt = params[0];
vt = params[1];
}
return buildMapEntrySerializer(prov.getConfig(), type, beanDesc, staticTyping, kt, vt);
}
if (ByteBuffer.class.isAssignableFrom(raw)) {
return new ByteBufferSerializer();
}
if (InetAddress.class.isAssignableFrom(raw)) {
return new InetAddressSerializer();
}
if (InetSocketAddress.class.isAssignableFrom(raw)) {
return new InetSocketAddressSerializer();
}
if (TimeZone.class.isAssignableFrom(raw)) {
return new TimeZoneSerializer();
}
if (java.nio.charset.Charset.class.isAssignableFrom(raw)) {
return ToStringSerializer.instance;
}
if (Number.class.isAssignableFrom(raw)) {
// 21-May-2014, tatu: Couple of alternatives actually
JsonFormat.Value format = beanDesc.findExpectedFormat(null);
if (format != null) {
switch (format.getShape()) {
case STRING:
return ToStringSerializer.instance;
case OBJECT: // need to bail out to let it be serialized as POJO
case ARRAY: // or, I guess ARRAY; otherwise no point in speculating
return null;
default:
}
}
return NumberSerializer.instance;
}
if (Enum.class.isAssignableFrom(raw)) {
return buildEnumSerializer(prov.getConfig(), type, beanDesc);
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> return null;
}
/**
* Overridable method called after checking all other types.
*
* @since 2.2
*/
protected JsonSerializer<?> findOptionalStdSerializer(SerializerProvider prov,
JavaType type, BeanDescription beanDesc, boolean staticTyping)
throws JsonMappingException
{
return OptionalHandlerFactory.instance.findSerializer(prov.getConfig(), type, beanDesc);
}
/**
* Reflection-based serialized find method, which checks if
* given class implements one of recognized "add-on" interfaces.
* Add-on here means a role that is usually or can be a secondary
* trait: for example,
* bean classes may implement {@link Iterable}, but their main
* function is usually something else. The reason for
*/
protected final JsonSerializer<?> findSerializerByAddonType(SerializationConfig config,
JavaType javaType, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException
{
Class<?> type = javaType.getRawClass();
if (Iterator.class.isAssignableFrom(type)) {
JavaType[] params = config.getTypeFactory().findTypeParameters(javaType, Iterator.class);
JavaType vt = (params == null || params.length != 1) ?
TypeFactory.unknownType() : params[0];
return buildIteratorSerializer(config, javaType, beanDesc, staticTyping, vt);
}
if (Iterable.class.isAssignableFrom(type)) {
JavaType[] params = config.getTypeFactory().findTypeParameters(javaType, Iterable.class);
JavaType vt = (params == null || params.length != 1) ?
TypeFactory.unknownType() : params[0];
return buildIterableSerializer(config, javaType, beanDesc, staticTyping, vt);
}
if (CharSequence.class.isAssignableFrom(type)) {
return ToStringSerializer.instance;
}
return null;
}
/**
* Helper method called to check if a class or method
* has an annotation
* (@link com.fasterxml.jackson.databind.annotation.JsonSerialize#using)
* that tells the class to use for serialization.
* Returns null if no such annotation found.
*/
@SuppressWarnings("unchecked")
protected JsonSerializer<Object> findSerializerFromAnnotation(SerializerProvider prov,
Annotated a)
throws JsonMappingException
{
Object serDef = prov.getAnnotationIntrospector().findSerializer(a);
if (serDef == null) {
return null;
}
JsonSerializer<Object> ser = prov.serializerInstance(a, serDef);
// One more thing however: may need to also apply a converter:
return (JsonSerializer<Object>) findConvertingSerializer(prov, a, ser);
}
/**
* Helper method that will check whether
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer)
throws JsonMappingException
{
JsonSerializer<?> ser = null;
// Module-provided custom collection serializers?
for (Serializers serializers : customSerializers()) {
ser = serializers.findCollectionSerializer(config,
type, beanDesc, elementTypeSerializer, elementValueSerializer);
if (ser != null) {
break;
}
}
if (ser == null) {
// We may also want to use serialize Collections "as beans", if (and only if)
// this is specified with `@JsonFormat(shape=Object)`
JsonFormat.Value format = beanDesc.findExpectedFormat(null);
if (format != null && format.getShape() == JsonFormat.Shape.OBJECT) {
return null;
}
Class<?> raw = type.getRawClass();
if (EnumSet.class.isAssignableFrom(raw)) {
// this may or may not be available (Class doesn't; type of field/method does)
JavaType enumType = type.getContentType();
// and even if nominally there is something, only use if it really is enum
if (!enumType.isEnumType()) {
enumType = null;
}
ser = buildEnumSetSerializer(enumType);
} else {
Class<?> elementRaw = type.getContentType().getRawClass();
if (isIndexedList(raw)) {
if (elementRaw == String.class) {
// [JACKSON-829] Must NOT use if we have custom serializer
if (elementValueSerializer == null || ClassUtil.isJacksonStdImpl(elementValueSerializer)) {
ser = IndexedStringListSerializer.instance;
}
} else {
ser = buildIndexedListSerializer(type.getContentType(), staticTyping,
elementTypeSerializer, elementValueSerializer);
}
} else if (elementRaw == String.class) {
// [JACKSON-829] Must NOT use if we have custom serializer
if (elementValueSerializer == null || ClassUtil.isJacksonStdImpl(elementValueSerializer)) {
ser = StringCollectionSerializer.instance;
}
}
if (ser == null) {
ser = buildCollectionSerializer(type.getContentType(), staticTyping,
elementTypeSerializer, elementValueSerializer);
}
}
}
// [Issue#120]: Allow post-processing
if (_factoryConfig.hasSerializerModifiers()) {
for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
ser = mod.modifyCollectionSerializer(config, type, beanDesc, ser);
}
}
return ser;
}
/*
/**********************************************************
/* Factory methods, for Collections
/**********************************************************
*/
protected boolean is
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>IndexedList(Class<?> cls)
{
return RandomAccess.class.isAssignableFrom(cls);
}
public ContainerSerializer<?> buildIndexedListSerializer(JavaType elemType,
boolean staticTyping, TypeSerializer vts, JsonSerializer<Object> valueSerializer) {
return new IndexedListSerializer(elemType, staticTyping, vts, null, valueSerializer);
}
public ContainerSerializer<?> buildCollectionSerializer(JavaType elemType,
boolean staticTyping, TypeSerializer vts, JsonSerializer<Object> valueSerializer) {
return new CollectionSerializer(elemType, staticTyping, vts, null, valueSerializer);
}
public JsonSerializer<?> buildEnumSetSerializer(JavaType enumType) {
return new EnumSetSerializer(enumType, null);
}
/*
/**********************************************************
/* Factory methods, for Maps
/**********************************************************
*/
/**
* Helper method that handles configuration details when constructing serializers for
* {@link java.util.Map} types.
*/
protected JsonSerializer<?> buildMapSerializer(SerializationConfig config,
MapType type, BeanDescription beanDesc,
boolean staticTyping, JsonSerializer<Object> keySerializer,
TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer)
throws JsonMappingException
{
JsonSerializer<?> ser = null;
for (Serializers serializers : customSerializers()) {
ser = serializers.findMapSerializer(config, type, beanDesc,
keySerializer, elementTypeSerializer, elementValueSerializer);
if (ser != null) { break; }
}
if (ser == null) {
// 08-Nov-2014, tatu: As per [databind#601], better just use default Map serializer
/*
if (EnumMap.class.isAssignableFrom(type.getRawClass())
&& ((keySerializer == null) || ClassUtil.isJacksonStdImpl(keySerializer))) {
JavaType keyType = type.getKeyType();
// Need to find key enum values...
EnumValues enums = null;
if (keyType.isEnumType()) { // non-enum if we got it as type erased class (from instance)
@SuppressWarnings("unchecked")
Class<Enum<?>> enumClass = (Class<Enum<?>>) keyType.getRawClass();
enums = EnumValues.construct(config, enumClass);
}
ser = new EnumMapSerializer(type.getContentType(), staticTyping, enums,
elementTypeSerializer, elementValueSerializer);
} else {
*/
Object filterId = findFilterId(config, beanDesc);
MapSerializer mapSer = MapSerializer.construct(config.getAnnotationIntrospector().findPropertiesToIgnore(beanDesc.getClassInfo()),
type, staticTyping, elementTypeSerializer,
keySerializer, elementValueSerializer, filterId);
Object suppressableValue
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> = findSuppressableContentValue(config,
type.getContentType(), beanDesc);
if (suppressableValue != null) {
mapSer = mapSer.withContentInclusion(suppressableValue);
}
ser = mapSer;
}
// [Issue#120]: Allow post-processing
if (_factoryConfig.hasSerializerModifiers()) {
for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
ser = mod.modifyMapSerializer(config, type, beanDesc, ser);
}
}
return ser;
}
/**
* @since 2.5
*/
protected Object findSuppressableContentValue(SerializationConfig config,
JavaType contentType, BeanDescription beanDesc)
throws JsonMappingException
{
JsonInclude.Include incl = beanDesc.findSerializationInclusionForContent(null);
if (incl != null) {
switch (incl) {
case NON_DEFAULT:
// 19-Oct-2014, tatu: Not sure what this'd mean; so take it to mean "NON_EMPTY"...
incl = JsonInclude.Include.NON_EMPTY;
break;
default:
// all other modes actually good as is, unless we'll find better ways
break;
}
return incl;
}
return null;
}
/*
/**********************************************************
/* Factory methods, for Arrays
/**********************************************************
*/
/**
* Helper method that handles configuration details when constructing serializers for
* <code>Object[]</code> (and subtypes, except for String).
*/
protected JsonSerializer<?> buildArraySerializer(SerializationConfig config,
ArrayType type, BeanDescription beanDesc,
boolean staticTyping,
TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer)
throws JsonMappingException
{
JsonSerializer<?> ser = null;
// Module-provided custom collection serializers?
for (Serializers serializers : customSerializers()) {
ser = serializers.findArraySerializer(config,
type, beanDesc, elementTypeSerializer, elementValueSerializer);
if (ser != null) {
break;
}
}
if (ser == null) {
Class<?> raw = type.getRawClass();
// Important: do NOT use standard serializers if non-standard element value serializer specified
if (elementValueSerializer == null || ClassUtil.isJacksonStdImpl(elementValueSerializer)) {
if (String[].class == raw) {
ser = StringArraySerializer.instance;
} else {
// other standard types?
ser = StdArraySerializers.findStandardImpl(raw);
}
}
if (ser == null) {
ser = new ObjectArraySerializer(type.getContentType(), staticTyping, elementTypeSerializer,
elementValueSerializer);
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> shape, serialize as JSON Object.
* Challenge here is that EnumSerializer does not know how to produce
* POJO style serialization, so we must handle that special case separately;
* otherwise pass it to EnumSerializer.
*/
JsonFormat.Value format = beanDesc.findExpectedFormat(null);
if (format != null && format.getShape() == JsonFormat.Shape.OBJECT) {
// one special case: suppress serialization of "getDeclaringClass()"...
((BasicBeanDescription) beanDesc).removeProperty("declaringClass");
// returning null will mean that eventually BeanSerializer gets constructed
return null;
}
@SuppressWarnings("unchecked")
Class<Enum<?>> enumClass = (Class<Enum<?>>) type.getRawClass();
JsonSerializer<?> ser = EnumSerializer.construct(enumClass, config, beanDesc, format);
// [Issue#120]: Allow post-processing
if (_factoryConfig.hasSerializerModifiers()) {
for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
ser = mod.modifyEnumSerializer(config, type, beanDesc, ser);
}
}
return ser;
}
/*
/**********************************************************
/* Other helper methods
/**********************************************************
*/
/**
* Helper method used to encapsulate details of annotation-based type coercion
*/
@SuppressWarnings("unchecked")
protected <T extends JavaType> T modifyTypeByAnnotation(SerializationConfig config,
Annotated a, T type)
{
// first: let's check class for the instance itself:
Class<?> superclass = config.getAnnotationIntrospector().findSerializationType(a);
if (superclass != null) {
try {
type = (T) type.widenBy(superclass);
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException("Failed to widen type "+type+" with concrete-type annotation (value "+superclass.getName()+"), method '"+a.getName()+"': "+iae.getMessage());
}
}
return modifySecondaryTypesByAnnotation(config, a, type);
}
@SuppressWarnings("unchecked")
protected static <T extends JavaType> T modifySecondaryTypesByAnnotation(SerializationConfig config,
Annotated a, T type)
{
AnnotationIntrospector intr = config.getAnnotationIntrospector();
// then key class
if (type.isContainerType()) {
Class<?> keyClass = intr.findSerializationKeyType(a, type.getKeyType());
if (keyClass != null) {
// illegal to use on non-Maps
if (!(type instanceof MapType)) {
throw new IllegalArgumentException("Illegal key-type annotation: type "+type+" is not a Map type");
}
try {
type = (T) ((MapType) type).widenKey(
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>keyClass);
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException("Failed to narrow key type "+type+" with key-type annotation ("+keyClass.getName()+"): "+iae.getMessage());
}
}
// and finally content class; only applicable to structured types
Class<?> cc = intr.findSerializationContentType(a, type.getContentType());
if (cc != null) {
try {
type = (T) type.widenContentsBy(cc);
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException("Failed to narrow content type "+type+" with content-type annotation ("+cc.getName()+"): "+iae.getMessage());
}
}
}
return type;
}
/**
* Helper method called to try to find whether there is an annotation in the
* class that indicates key serializer to use.
* If so, will try to instantiate key serializer and return it; otherwise returns null.
*/
protected JsonSerializer<Object> _findKeySerializer(SerializerProvider prov,
Annotated a)
throws JsonMappingException
{
AnnotationIntrospector intr = prov.getAnnotationIntrospector();
Object serDef = intr.findKeySerializer(a);
if (serDef != null) {
return prov.serializerInstance(a, serDef);
}
return null;
}
/**
* Helper method called to try to find whether there is an annotation in the
* class that indicates content ("value") serializer to use.
* If so, will try to instantiate key serializer and return it; otherwise returns null.
*/
protected JsonSerializer<Object> _findContentSerializer(SerializerProvider prov,
Annotated a)
throws JsonMappingException
{
AnnotationIntrospector intr = prov.getAnnotationIntrospector();
Object serDef = intr.findContentSerializer(a);
if (serDef != null) {
return prov.serializerInstance(a, serDef);
}
return null;
}
/**
* Method called to find filter that is configured to be used with bean
* serializer being built, if any.
*/
protected Object findFilterId(SerializationConfig config, BeanDescription beanDesc) {
return config.getAnnotationIntrospector().findFilterId((Annotated)beanDesc.getClassInfo());
}
/**
* Helper method to check whether global settings and/or class
* annotations for the bean class indicate that static typing
* (declared types) should be used for properties.
* (instead of dynamic runtime types).
*
* @since 2.1 (earlier had variant with additional 'property' parameter)
*/
protected boolean usesStaticTyping(SerializationConfig config,
BeanDescription beanDesc, TypeSerializer typeSer)
{
/* 16-Aug-2010, t
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>atu: If there is a (value) type serializer, we can not force
* static typing; that would make it impossible to handle expected subtypes
*/
if (typeSer != null) {
return false;
}
AnnotationIntrospector intr = config.getAnnotationIntrospector();
JsonSerialize.Typing t = intr.findSerializationTyping(beanDesc.getClassInfo());
if (t != null && t != JsonSerialize.Typing.DEFAULT_TYPING) {
return (t == JsonSerialize.Typing.STATIC);
}
return config.isEnabled(MapperFeature.USE_STATIC_TYPING);
}
protected Class<?> _verifyAsClass(Object src, String methodName, Class<?> noneClass)
{
if (src == null) {
return null;
}
if (!(src instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector."+methodName+"() returned value of type "+src.getClass().getName()+": expected type JsonSerializer or Class<JsonSerializer> instead");
}
Class<?> cls = (Class<?>) src;
if (cls == noneClass || ClassUtil.isBogusClass(cls)) {
return null;
}
return cls;
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.impl;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
/**
* Simple deserializer that will call configured type deserializer, passing
* in configured data deserializer, and exposing it all as a simple
* deserializer.
* This is necessary when there is no "parent" deserializer which could handle
* details of calling a {@link TypeDeserializer}, most commonly used with
* root values.
*/
public final class TypeWrappedDeserializer
extends JsonDeserializer<Object>
implements java.io.Serializable // since 2.5
{
private static final long serialVersionUID = 1L;
final protected TypeDeserializer _typeDeserializer;
final protected JsonDeserializer<Object> _deserializer;
@SuppressWarnings("unchecked")
public TypeWrappedDeserializer(TypeDeserializer typeDeser, JsonDeserializer<?> deser)
{
super();
_typeDeserializer = typeDeser;
_deserializer = (JsonDeserializer<Object>) deser;
}
@Override
public Class<?> handledType() {
return _deserializer.handledType();
}
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
{
return _deserializer.deserializeWithType(jp, ctxt, _typeDeserializer);
}
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt,
TypeDeserializer typeDeserializer) throws IOException
{
// should never happen? (if it can, could call on that object)
throw new IllegalStateException("Type-wrapped deserializer's deserializeWithType should never get called");
}
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt,
Object intoValue) throws IOException
{
/* 01-Mar-2013, tatu: Hmmh. Tough call as to what to do... need
* to delegate, but will this work reliably? Let's just hope so:
*/
return _deserializer.deserialize(jp, ctxt, intoValue);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>}s to enable/disable.
*/
protected final int _generatorFeatures;
/**
* Bitflag of {@link com.fasterxml.jackson.core.JsonGenerator.Feature}s to enable/disable
*/
protected final int _generatorFeaturesToChange;
/*
/**********************************************************
/* Life-cycle, constructors
/**********************************************************
*/
/**
* Constructor used by ObjectMapper to create default configuration object instance.
*/
public SerializationConfig(BaseSettings base,
SubtypeResolver str, Map<ClassKey,Class<?>> mixins)
{
super(base, str, mixins);
_serFeatures = collectFeatureDefaults(SerializationFeature.class);
_filterProvider = null;
_generatorFeatures = 0;
_generatorFeaturesToChange = 0;
}
private SerializationConfig(SerializationConfig src, SubtypeResolver str)
{
super(src, str);
_serFeatures = src._serFeatures;
_serializationInclusion = src._serializationInclusion;
_filterProvider = src._filterProvider;
_generatorFeatures = src._generatorFeatures;
_generatorFeaturesToChange = src._generatorFeaturesToChange;
}
private SerializationConfig(SerializationConfig src,
int mapperFeatures, int serFeatures,
int generatorFeatures, int generatorFeatureMask)
{
super(src, mapperFeatures);
_serFeatures = serFeatures;
_serializationInclusion = src._serializationInclusion;
_filterProvider = src._filterProvider;
_generatorFeatures = generatorFeatures;
_generatorFeaturesToChange = generatorFeatureMask;
}
private SerializationConfig(SerializationConfig src, BaseSettings base)
{
super(src, base);
_serFeatures = src._serFeatures;
_serializationInclusion = src._serializationInclusion;
_filterProvider = src._filterProvider;
_generatorFeatures = src._generatorFeatures;
_generatorFeaturesToChange = src._generatorFeaturesToChange;
}
private SerializationConfig(SerializationConfig src, FilterProvider filters)
{
super(src);
_serFeatures = src._serFeatures;
_serializationInclusion = src._serializationInclusion;
_filterProvider = filters;
_generatorFeatures = src._generatorFeatures;
_generatorFeaturesToChange = src._generatorFeaturesToChange;
}
private SerializationConfig(SerializationConfig src, Class<?> view)
{
super(src, view);
_serFeatures = src._serFeatures;
_serializationInclusion = src._serializationInclusion;
_filterProvider = src._filterProvider;
_generatorFeatures = src._generatorFeatures;
_generatorFeaturesToChange = src._generatorFeaturesToChange;
}
private SerializationConfig(SerializationConfig src, JsonInclude.Include incl)
{
super(src);
_serFeatures = src
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>._serFeatures;
_serializationInclusion = incl;
_filterProvider = src._filterProvider;
_generatorFeatures = src._generatorFeatures;
_generatorFeaturesToChange = src._generatorFeaturesToChange;
}
private SerializationConfig(SerializationConfig src, String rootName)
{
super(src, rootName);
_serFeatures = src._serFeatures;
_serializationInclusion = src._serializationInclusion;
_filterProvider = src._filterProvider;
_generatorFeatures = src._generatorFeatures;
_generatorFeaturesToChange = src._generatorFeaturesToChange;
}
/**
* @since 2.1
*/
protected SerializationConfig(SerializationConfig src, Map<ClassKey,Class<?>> mixins)
{
super(src, mixins);
_serFeatures = src._serFeatures;
_serializationInclusion = src._serializationInclusion;
_filterProvider = src._filterProvider;
_generatorFeatures = src._generatorFeatures;
_generatorFeaturesToChange = src._generatorFeaturesToChange;
}
/**
* @since 2.1
*/
protected SerializationConfig(SerializationConfig src, ContextAttributes attrs)
{
super(src, attrs);
_serFeatures = src._serFeatures;
_serializationInclusion = src._serializationInclusion;
_filterProvider = src._filterProvider;
_generatorFeatures = src._generatorFeatures;
_generatorFeaturesToChange = src._generatorFeaturesToChange;
}
/*
/**********************************************************
/* Life-cycle, factory methods from MapperConfig
/**********************************************************
*/
/**
* Fluent factory method that will construct and return a new configuration
* object instance with specified features enabled.
*/
@Override
public SerializationConfig with(MapperFeature... features)
{
int newMapperFlags = _mapperFeatures;
for (MapperFeature f : features) {
newMapperFlags |= f.getMask();
}
return (newMapperFlags == _mapperFeatures) ? this
: new SerializationConfig(this, newMapperFlags, _serFeatures,
_generatorFeatures, _generatorFeaturesToChange);
}
/**
* Fluent factory method that will construct and return a new configuration
* object instance with specified features disabled.
*/
@Override
public SerializationConfig without(MapperFeature... features)
{
int newMapperFlags = _mapperFeatures;
for (MapperFeature f : features) {
newMapperFlags &= ~f.getMask();
}
return (newMapperFlags == _mapperFeatures) ? this
: new SerializationConfig(this, newMapperFlags, _serFeatures,
_generatorFeatures, _generatorFeaturesToChange);
}
@Override
public SerializationConfig with(MapperFeature feature, boolean state)
{
int newMapperFlags;
if (
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
public SerializationConfig with(TypeResolverBuilder<?> trb) {
return _withBase(_base.withTypeResolverBuilder(trb));
}
@Override
public SerializationConfig withView(Class<?> view) {
return (_view == view) ? this : new SerializationConfig(this, view);
}
@Override
public SerializationConfig with(VisibilityChecker<?> vc) {
return _withBase(_base.withVisibilityChecker(vc));
}
@Override
public SerializationConfig withVisibility(PropertyAccessor forMethod, JsonAutoDetect.Visibility visibility) {
return _withBase(_base.withVisibility(forMethod, visibility));
}
@Override
public SerializationConfig with(Locale l) {
return _withBase(_base.with(l));
}
@Override
public SerializationConfig with(TimeZone tz) {
return _withBase(_base.with(tz));
}
@Override
public SerializationConfig with(Base64Variant base64) {
return _withBase(_base.with(base64));
}
@Override
public SerializationConfig with(ContextAttributes attrs) {
return (attrs == _attributes) ? this : new SerializationConfig(this, attrs);
}
private final SerializationConfig _withBase(BaseSettings newBase) {
return (_base == newBase) ? this : new SerializationConfig(this, newBase);
}
/*
/**********************************************************
/* Factory methods for SerializationFeature
/**********************************************************
*/
/**
* Fluent factory method that will construct and return a new configuration
* object instance with specified feature enabled.
*/
public SerializationConfig with(SerializationFeature feature)
{
int newSerFeatures = _serFeatures | feature.getMask();
return (newSerFeatures == _serFeatures) ? this
: new SerializationConfig(this, _mapperFeatures, newSerFeatures,
_generatorFeatures, _generatorFeaturesToChange);
}
/**
* Fluent factory method that will construct and return a new configuration
* object instance with specified features enabled.
*/
public SerializationConfig with(SerializationFeature first, SerializationFeature... features)
{
int newSerFeatures = _serFeatures | first.getMask();
for (SerializationFeature f : features) {
newSerFeatures |= f.getMask();
}
return (newSerFeatures == _serFeatures) ? this
: new SerializationConfig(this, _mapperFeatures, newSerFeatures,
_generatorFeatures, _generatorFeaturesToChange);
}
/**
* Fluent factory method that will construct and return a new configuration
* object instance with specified features enabled.
*/
public SerializationConfig withFeatures(SerializationFeature... features)
{
int newSerFeatures = _serFeatures;
for (SerializationFeature f : features) {
newSerFeatures |= f
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Desc;
_canFixAccess = canFixAccess;
}
public ValueInstantiator constructValueInstantiator(DeserializationConfig config)
{
JavaType delegateType;
boolean maybeVanilla = !_hasNonDefaultCreator;
if (maybeVanilla || (_creators[C_DELEGATE] == null)) {
delegateType = null;
} else {
// need to find type...
int ix = 0;
if (_delegateArgs != null) {
for (int i = 0, len = _delegateArgs.length; i < len; ++i) {
if (_delegateArgs[i] == null) { // marker for delegate itself
ix = i;
break;
}
}
}
TypeBindings bindings = _beanDesc.bindingsForBeanType();
delegateType = bindings.resolveType(_creators[C_DELEGATE].getGenericParameterType(ix));
}
final JavaType type = _beanDesc.getType();
// Any non-standard creator will prevent; with one exception: int-valued constructor
// that standard containers have can be ignored
maybeVanilla &= !_hasNonDefaultCreator;
if (maybeVanilla) {
/* 10-May-2014, tatu: If we have nothing special, and we are dealing with one
* of "well-known" types, can create a non-reflection-based instantiator.
*/
final Class<?> rawType = type.getRawClass();
if (rawType == Collection.class || rawType == List.class || rawType == ArrayList.class) {
return new Vanilla(Vanilla.TYPE_COLLECTION);
}
if (rawType == Map.class || rawType == LinkedHashMap.class) {
return new Vanilla(Vanilla.TYPE_MAP);
}
if (rawType == HashMap.class) {
return new Vanilla(Vanilla.TYPE_HASH_MAP);
}
}
StdValueInstantiator inst = new StdValueInstantiator(config, type);
inst.configureFromObjectSettings(_creators[C_DEFAULT],
_creators[C_DELEGATE], delegateType, _delegateArgs,
_creators[C_PROPS], _propertyBasedArgs);
inst.configureFromStringCreator(_creators[C_STRING]);
inst.configureFromIntCreator(_creators[C_INT]);
inst.configureFromLongCreator(_creators[C_LONG]);
inst.configureFromDoubleCreator(_creators[C_DOUBLE]);
inst.configureFromBooleanCreator(_creators[C_BOOLEAN]);
inst.configureIncompleteParameter(_incompleteParameter);
return inst;
}
/*
/**********************************************************
/* Setters
/**********************************************************
*/
/**
* Method
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> in sub-class
if (verify && (oldOne.getClass() == newOne.getClass())) {
// [databind#667]: avoid one particular class of bogus problems
Class<?> oldType = oldOne.getRawParameterType(0);
Class<?> newType = newOne.getRawParameterType(0);
if (oldType == newType) {
throw new IllegalArgumentException("Conflicting "+TYPE_DESCS[typeIndex]
+" creators: already had explicitly marked "+oldOne+", encountered "+newOne);
}
// otherwise, which one to choose?
if (newType.isAssignableFrom(oldType)) {
// new type more generic, use old
return;
}
// new type more specific, use it
}
}
if (explicit) {
_explicitCreators |= mask;
}
_creators[typeIndex] = _fixAccess(newOne);
}
/*
/**********************************************************
/* Helper class(es)
/**********************************************************
*/
protected final static class Vanilla
extends ValueInstantiator
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
public final static int TYPE_COLLECTION = 1;
public final static int TYPE_MAP = 2;
public final static int TYPE_HASH_MAP = 3;
private final int _type;
public Vanilla(int t) {
_type = t;
}
@Override
public String getValueTypeDesc() {
switch (_type) {
case TYPE_COLLECTION: return ArrayList.class.getName();
case TYPE_MAP: return LinkedHashMap.class.getName();
case TYPE_HASH_MAP: return HashMap.class.getName();
}
return Object.class.getName();
}
@Override
public boolean canInstantiate() { return true; }
@Override
public boolean canCreateUsingDefault() { return true; }
@Override
public Object createUsingDefault(DeserializationContext ctxt) throws IOException {
switch (_type) {
case TYPE_COLLECTION: return new ArrayList<Object>();
case TYPE_MAP: return new LinkedHashMap<String,Object>();
case TYPE_HASH_MAP: return new HashMap<String,Object>();
}
throw new IllegalStateException("Unknown type "+_type);
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>(ctxt);
_incompleteDeserializers.remove(type);
}
if (addToCache) {
_cachedDeserializers.put(type, deser);
}
return deser;
}
/*
/**********************************************************
/* Helper methods for actual construction of deserializers
/**********************************************************
*/
/**
* Method that does the heavy lifting of checking for per-type annotations,
* find out full type, and figure out which actual factory method
* to call.
*/
@SuppressWarnings("unchecked")
protected JsonDeserializer<Object> _createDeserializer(DeserializationContext ctxt,
DeserializerFactory factory, JavaType type)
throws JsonMappingException
{
final DeserializationConfig config = ctxt.getConfig();
// First things first: do we need to use abstract type mapping?
if (type.isAbstract() || type.isMapLikeType() || type.isCollectionLikeType()) {
type = factory.mapAbstractType(config, type);
}
BeanDescription beanDesc;
try {
beanDesc = config.introspect(type);
} catch (NoClassDefFoundError error) {
return new NoClassDefFoundDeserializer<Object>(error);
}
// Then: does type define explicit deserializer to use, with annotation(s)?
JsonDeserializer<Object> deser = findDeserializerFromAnnotation(ctxt,
beanDesc.getClassInfo());
if (deser != null) {
return deser;
}
// If not, may have further type-modification annotations to check:
JavaType newType = modifyTypeByAnnotation(ctxt, beanDesc.getClassInfo(), type);
if (newType != type) {
type = newType;
beanDesc = config.introspect(newType);
}
// We may also have a Builder type to consider...
Class<?> builder = beanDesc.findPOJOBuilder();
if (builder != null) {
return (JsonDeserializer<Object>) factory.createBuilderBasedDeserializer(
ctxt, type, beanDesc, builder);
}
// Or perhaps a Converter?
Converter<Object,Object> conv = beanDesc.findDeserializationConverter();
if (conv == null) { // nope, just construct in normal way
return (JsonDeserializer<Object>) _createDeserializer2(ctxt, factory, type, beanDesc);
}
// otherwise need to do bit of introspection
JavaType delegateType = conv.getInputType(ctxt.getTypeFactory());
// One more twist, as per [Issue#288]; probably need to get new BeanDesc
if (!delegateType.hasRawClass(type.getRawClass())) {
beanDesc = config.introspect(delegateType);
}
return new StdDelegatingDeserializer<Object>(conv, delegateType,
_createDeserializer2(ctxt
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>, ann, deser);
}
/**
* Helper method that will check whether given annotated entity (usually class,
* but may also be a property accessor) indicates that a {@link Converter} is to
* be used; and if so, to construct and return suitable serializer for it.
* If not, will simply return given serializer as is.
*/
protected JsonDeserializer<Object> findConvertingDeserializer(DeserializationContext ctxt,
Annotated a, JsonDeserializer<Object> deser)
throws JsonMappingException
{
Converter<Object,Object> conv = findConverter(ctxt, a);
if (conv == null) {
return deser;
}
JavaType delegateType = conv.getInputType(ctxt.getTypeFactory());
return (JsonDeserializer<Object>) new StdDelegatingDeserializer<Object>(conv, delegateType, deser);
}
protected Converter<Object,Object> findConverter(DeserializationContext ctxt,
Annotated a)
throws JsonMappingException
{
Object convDef = ctxt.getAnnotationIntrospector().findDeserializationConverter(a);
if (convDef == null) {
return null;
}
return ctxt.converterInstance(a, convDef);
}
/**
* Method called to see if given method has annotations that indicate
* a more specific type than what the argument specifies.
* If annotations are present, they must specify compatible Class;
* instance of which can be assigned using the method. This means
* that the Class has to be raw class of type, or its sub-class
* (or, implementing class if original Class instance is an interface).
*
* @param a Method or field that the type is associated with
* @param type Type derived from the setter argument
*
* @return Original type if no annotations are present; or a more
* specific type derived from it if type annotation(s) was found
*
* @throws JsonMappingException if invalid annotation is found
*/
private JavaType modifyTypeByAnnotation(DeserializationContext ctxt,
Annotated a, JavaType type)
throws JsonMappingException
{
// first: let's check class for the instance itself:
AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
Class<?> subclass = intr.findDeserializationType(a, type);
if (subclass != null) {
try {
type = type.narrowBy(subclass);
} catch (IllegalArgumentException iae) {
throw new JsonMappingException("Failed to narrow type "+type+" with concrete-type annotation (value "+subclass.getName()+"), method '"+a.getName()+"': "+iae.getMessage(), null, iae);
}
}
// then key class
if (type.isContainerType()) {
Class<?> keyClass = intr.findDeserializationKeyType(a, type.getKey
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Type());
if (keyClass != null) {
// illegal to use on non-Maps
if (!(type instanceof MapLikeType)) {
throw new JsonMappingException("Illegal key-type annotation: type "+type+" is not a Map(-like) type");
}
try {
type = ((MapLikeType) type).narrowKey(keyClass);
} catch (IllegalArgumentException iae) {
throw new JsonMappingException("Failed to narrow key type "+type+" with key-type annotation ("+keyClass.getName()+"): "+iae.getMessage(), null, iae);
}
}
JavaType keyType = type.getKeyType();
/* 21-Mar-2011, tatu: ... and associated deserializer too (unless already assigned)
* (not 100% why or how, but this does seem to get called more than once, which
* is not good: for now, let's just avoid errors)
*/
if (keyType != null && keyType.getValueHandler() == null) {
Object kdDef = intr.findKeyDeserializer(a);
if (kdDef != null) {
KeyDeserializer kd = ctxt.keyDeserializerInstance(a, kdDef);
if (kd != null) {
type = ((MapLikeType) type).withKeyValueHandler(kd);
keyType = type.getKeyType(); // just in case it's used below
}
}
}
// and finally content class; only applicable to structured types
Class<?> cc = intr.findDeserializationContentType(a, type.getContentType());
if (cc != null) {
try {
type = type.narrowContentsBy(cc);
} catch (IllegalArgumentException iae) {
throw new JsonMappingException("Failed to narrow content type "+type+" with content-type annotation ("+cc.getName()+"): "+iae.getMessage(), null, iae);
}
}
// ... as well as deserializer for contents:
JavaType contentType = type.getContentType();
if (contentType.getValueHandler() == null) { // as with above, avoid resetting (which would trigger exception)
Object cdDef = intr.findContentDeserializer(a);
if (cdDef != null) {
JsonDeserializer<?> cd = null;
if (cdDef instanceof JsonDeserializer<?>) {
cdDef = (JsonDeserializer<?>) cdDef;
} else {
Class<?> cdClass = _verifyAsClass(cdDef, "findContentDeserializer", JsonDeserializer.None.class);
if (cdClass != null) {
cd = ctxt.deserializerInstance(a, cdClass);
}
}
if (cd != null) {
type = type.withContentValueHandler(cd);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
}
}
return type;
}
private Class<?> _verifyAsClass(Object src, String methodName, Class<?> noneClass)
{
if (src == null) {
return null;
}
if (!(src instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector."+methodName+"() returned value of type "+src.getClass().getName()+": expected type JsonSerializer or Class<JsonSerializer> instead");
}
Class<?> cls = (Class<?>) src;
if (cls == noneClass || ClassUtil.isBogusClass(cls)) {
return null;
}
return cls;
}
/*
/**********************************************************
/* Overridable error reporting methods
/**********************************************************
*/
protected JsonDeserializer<Object> _handleUnknownValueDeserializer(JavaType type)
throws JsonMappingException
{
/* Let's try to figure out the reason, to give better error
* messages
*/
Class<?> rawClass = type.getRawClass();
if (!ClassUtil.isConcrete(rawClass)) {
throw new JsonMappingException("Can not find a Value deserializer for abstract type "+type);
}
throw new JsonMappingException("Can not find a Value deserializer for type "+type);
}
protected KeyDeserializer _handleUnknownKeyDeserializer(JavaType type)
throws JsonMappingException
{
throw new JsonMappingException("Can not find a (Map) Key deserializer for type "+type);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitable;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsonschema.SchemaAware;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.ResolvableSerializer;
import com.fasterxml.jackson.databind.util.Converter;
import java.io.IOException;
import java.lang.reflect.Type;
/**
* Serializer implementation where given Java type is first converted
* to an intermediate "delegate type" (using a configured
* {@link Converter}, and then this delegate value is serialized by Jackson.
*<p>
* Note that although types may be related, they must not be same; trying
* to do this will result in an exception.
*
* @since 2.1
*/
@SuppressWarnings("serial")
public class StdDelegatingSerializer
extends StdSerializer<Object>
implements ContextualSerializer, ResolvableSerializer,
JsonFormatVisitable, SchemaAware
{
protected final Converter<Object,?> _converter;
/**
* Fully resolved delegate type, with generic information if any available.
*/
protected final JavaType _delegateType;
/**
* Underlying serializer for type <code>T<.code>.
*/
protected final JsonSerializer<Object> _delegateSerializer;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
@SuppressWarnings("unchecked")
public StdDelegatingSerializer(Converter<?,?> converter)
{
super(Object.class);
_converter = (Converter<Object,?>)converter;
_delegateType = null;
_delegateSerializer = null;
}
@SuppressWarnings("unchecked")
public <T> StdDelegatingSerializer(Class<T> cls, Converter<T,?> converter)
{
super(cls, false);
_converter = (Converter<Object,?>)converter;
_delegateType = null;
_delegateSerializer = null;
}
@SuppressWarnings("unchecked")
public StdDelegatingSerializer(Converter<Object,?> converter,
JavaType delegateType, JsonSerializer<?> delegateSerializer)
{
super(delegateType);
_converter = converter;
_delegateType = delegateType;
_delegateSerializer = (JsonSerializer<Object>) delegateSerializer;
}
/**
* Method used for creating resolved contextual instances. Must be
* overridden when sub-classing.
*/
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.introspect;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Type;
import com.fasterxml.jackson.databind.util.ClassUtil;
/**
* Object that represents non-static (and usually non-transient/volatile)
* fields of a class.
*/
public final class AnnotatedField
extends AnnotatedMember
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
/**
* Actual {@link Field} used for access.
*<p>
* Transient since it can not be persisted directly using
* JDK serialization
*/
protected final transient Field _field;
/**
* Temporary field required for JDK serialization support
*/
protected Serialization _serialization;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public AnnotatedField(AnnotatedClass contextClass, Field field, AnnotationMap annMap)
{
super(contextClass, annMap);
_field = field;
}
@Override
public AnnotatedField withAnnotations(AnnotationMap ann) {
return new AnnotatedField(_context, _field, ann);
}
/**
* Method used for JDK serialization support
*/
protected AnnotatedField(Serialization ser)
{
super(null, null);
_field = null;
_serialization = ser;
}
/*
/**********************************************************
/* Annotated impl
/**********************************************************
*/
@Override
public Field getAnnotated() { return _field; }
@Override
public int getModifiers() { return _field.getModifiers(); }
@Override
public String getName() { return _field.getName(); }
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return (_annotations == null) ? null : _annotations.get(acls);
}
@Override
public Type getGenericType() {
return _field.getGenericType();
}
@Override
public Class<?> getRawType() {
return _field.getType();
}
/*
/**********************************************************
/* AnnotatedMember impl
/**********************************************************
*/
@Override
public Class<?> getDeclaringClass() { return _field.getDeclaringClass(); }
@Override
public Member getMember() { return _field; }
@Override
public void setValue(Object pojo, Object value) throws IllegalArgumentException
{
try {
_field.set(pojo, value);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException("Failed to setValue() for field "
+getFullName()+": "+e.getMessage(), e);
}
}
@Override
public
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> Object getValue(Object pojo) throws IllegalArgumentException
{
try {
return _field.get(pojo);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException("Failed to getValue() for field "
+getFullName()+": "+e.getMessage(), e);
}
}
/*
/**********************************************************
/* Extended API, generic
/**********************************************************
*/
public String getFullName() {
return getDeclaringClass().getName() + "#" + getName();
}
public int getAnnotationCount() { return _annotations.size(); }
@Override
public int hashCode() {
return _field.getName().hashCode();
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (o == null || o.getClass() != getClass()) return false;
return ((AnnotatedField) o)._field == _field;
}
@Override
public String toString() {
return "[field "+getFullName()+"]";
}
/*
/**********************************************************
/* JDK serialization handling
/**********************************************************
*/
Object writeReplace() {
return new AnnotatedField(new Serialization(_field));
}
Object readResolve() {
Class<?> clazz = _serialization.clazz;
try {
Field f = clazz.getDeclaredField(_serialization.name);
// 06-Oct-2012, tatu: Has "lost" its security override, may need to force back
if (!f.isAccessible()) {
ClassUtil.checkAndFixAccess(f);
}
return new AnnotatedField(null, f, null);
} catch (Exception e) {
throw new IllegalArgumentException("Could not find method '"+_serialization.name
+"' from Class '"+clazz.getName());
}
}
/**
* Helper class that is used as the workaround to persist
* Field references. It basically just stores declaring class
* and field name.
*/
private final static class Serialization
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
protected Class<?> clazz;
protected String name;
public Serialization(Field f) {
clazz = f.getDeclaringClass();
name = f.getName();
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>valueElem == null) {
provider.defaultSerializeNull(gen);
} else {
Class<?> cc = valueElem.getClass();
JsonSerializer<Object> serializer = serializers.serializerFor(cc);
if (serializer == null) {
if (_valueType.hasGenericTypes()) {
serializer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_valueType, cc), provider);
} else {
serializer = _findAndAddDynamic(serializers, cc, provider);
}
serializers = _dynamicValueSerializers;
}
try {
serializer.serialize(valueElem, gen, provider);
} catch (Exception e) {
// Add reference information
String keyDesc = ""+keyElem;
wrapAndThrow(provider, e, value, keyDesc);
}
}
}
}
public void serializeOptionalFields(Map<?,?> value, JsonGenerator gen, SerializerProvider provider,
Object suppressableValue)
throws IOException
{
// If value type needs polymorphic type handling, some more work needed:
if (_valueTypeSerializer != null) {
serializeTypedFields(value, gen, provider, suppressableValue);
return;
}
final HashSet<String> ignored = _ignoredEntries;
PropertySerializerMap serializers = _dynamicValueSerializers;
for (Map.Entry<?,?> entry : value.entrySet()) {
// First find key serializer
final Object keyElem = entry.getKey();
JsonSerializer<Object> keySerializer;
if (keyElem == null) {
keySerializer = provider.findNullKeySerializer(_keyType, _property);
} else {
if (ignored != null && ignored.contains(keyElem)) continue;
keySerializer = _keySerializer;
}
// Then value serializer
final Object valueElem = entry.getValue();
JsonSerializer<Object> valueSer;
if (valueElem == null) {
if (suppressableValue != null) { // all suppressions include null-suppression
continue;
}
valueSer = provider.getDefaultNullValueSerializer();
} else {
valueSer = _valueSerializer;
if (valueSer == null) {
Class<?> cc = valueElem.getClass();
valueSer = serializers.serializerFor(cc);
if (valueSer == null) {
if (_valueType.hasGenericTypes()) {
valueSer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_valueType, cc), provider);
} else {
valueSer = _findAndAddDynamic(serializers, cc, provider);
}
serializers = _dynamicValueSerializers;
}
}
// also may need to skip non-empty values:
if ((suppressableValue == JsonInclude.Include.NON_EMPTY)
&& valueSer.isEmpty(provider, valueElem))
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>keyType, _property);
} else {
keySerializer = _keySerializer;
}
// or by value; nulls often suppressed
final Object valueElem = entry.getValue();
JsonSerializer<Object> valueSer;
// And then value
if (valueElem == null) {
if (suppressableValue != null) { // all suppressions include null-suppression
continue;
}
valueSer = provider.getDefaultNullValueSerializer();
} else {
valueSer = _valueSerializer;
if (valueSer == null) {
Class<?> cc = valueElem.getClass();
valueSer = serializers.serializerFor(cc);
if (valueSer == null) {
if (_valueType.hasGenericTypes()) {
valueSer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_valueType, cc), provider);
} else {
valueSer = _findAndAddDynamic(serializers, cc, provider);
}
serializers = _dynamicValueSerializers;
}
}
// also may need to skip non-empty values:
if ((suppressableValue == JsonInclude.Include.NON_EMPTY)
&& valueSer.isEmpty(provider, valueElem)) {
continue;
}
}
// and with that, ask filter to handle it
prop.reset(keyElem, keySerializer, valueSer);
try {
filter.serializeAsField(valueElem, gen, provider, prop);
} catch (Exception e) {
String keyDesc = ""+keyElem;
wrapAndThrow(provider, e, value, keyDesc);
}
}
}
@Deprecated // since 2.5
public void serializeFilteredFields(Map<?,?> value, JsonGenerator gen, SerializerProvider provider,
PropertyFilter filter) throws IOException {
serializeFilteredFields(value, gen, provider, filter,
provider.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES) ? null : JsonInclude.Include.NON_NULL);
}
/**
* @since 2.5
*/
protected void serializeTypedFields(Map<?,?> value, JsonGenerator gen, SerializerProvider provider,
Object suppressableValue) // since 2.5
throws IOException
{
final HashSet<String> ignored = _ignoredEntries;
PropertySerializerMap serializers = _dynamicValueSerializers;
for (Map.Entry<?,?> entry : value.entrySet()) {
Object keyElem = entry.getKey();
JsonSerializer<Object> keySerializer;
if (keyElem == null) {
keySerializer = provider.findNullKeySerializer(_keyType, _property);
} else {
// One twist: is entry ignorable? If so, skip
if (ignored != null && ignored.contains(keyElem)) continue;
keySerializer = _key
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Serializer;
}
final Object valueElem = entry.getValue();
// And then value
JsonSerializer<Object> valueSer;
if (valueElem == null) {
if (suppressableValue != null) { // all suppression include null suppression
continue;
}
valueSer = provider.getDefaultNullValueSerializer();
} else {
valueSer = _valueSerializer;
Class<?> cc = valueElem.getClass();
valueSer = serializers.serializerFor(cc);
if (valueSer == null) {
if (_valueType.hasGenericTypes()) {
valueSer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_valueType, cc), provider);
} else {
valueSer = _findAndAddDynamic(serializers, cc, provider);
}
serializers = _dynamicValueSerializers;
}
// also may need to skip non-empty values:
if ((suppressableValue == JsonInclude.Include.NON_EMPTY)
&& valueSer.isEmpty(provider, valueElem)) {
continue;
}
}
keySerializer.serialize(keyElem, gen, provider);
try {
valueSer.serializeWithType(valueElem, gen, provider, _valueTypeSerializer);
} catch (Exception e) {
String keyDesc = ""+keyElem;
wrapAndThrow(provider, e, value, keyDesc);
}
}
}
@Deprecated // since 2.5
protected void serializeTypedFields(Map<?,?> value, JsonGenerator gen, SerializerProvider provider)
throws IOException {
serializeTypedFields(value, gen, provider,
provider.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES) ? null : JsonInclude.Include.NON_NULL);
}
/*
/**********************************************************
/* Schema related functionality
/**********************************************************
*/
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint)
{
ObjectNode o = createSchemaNode("object", true);
//(ryan) even though it's possible to statically determine the "value" type of the map,
// there's no way to statically determine the keys, so the "Entries" can't be determined.
return o;
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
throws JsonMappingException
{
JsonMapFormatVisitor v2 = (visitor == null) ? null : visitor.expectMapFormat(typeHint);
if (v2 != null) {
v2.keyFormat(_keySerializer, _keyType);
JsonSerializer<?> valueSer = _valueSerializer;
if (valueSer == null) {
valueSer = _findAndAddDynamic(_dynamicValueSerializers,
_valueType, visitor.getProvider());
}
v2
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>.valueFormat(valueSer, _valueType);
}
}
/*
/**********************************************************
/* Internal helper methods
/**********************************************************
*/
protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
Class<?> type, SerializerProvider provider) throws JsonMappingException
{
PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property);
// did we get a new map of serializers? If so, start using it
if (map != result.map) {
_dynamicValueSerializers = result.map;
}
return result.serializer;
}
protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
JavaType type, SerializerProvider provider) throws JsonMappingException
{
PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property);
if (map != result.map) {
_dynamicValueSerializers = result.map;
}
return result.serializer;
}
protected Map<?,?> _orderEntries(Map<?,?> input)
{
// minor optimization: may already be sorted?
if (input instanceof SortedMap<?,?>) {
return input;
}
return new TreeMap<Object,Object>(input);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import java.util.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.JsonParser.NumberType;
import com.fasterxml.jackson.core.io.NumberInput;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.Converter;
/**
* Base class for common deserializers. Contains shared
* base functionality for dealing with primitive values, such
* as (re)parsing from String.
*/
public abstract class StdDeserializer<T>
extends JsonDeserializer<T>
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
/**
* Type of values this deserializer handles: sometimes
* exact types, other time most specific supertype of
* types deserializer handles (which may be as generic
* as {@link Object} in some case)
*/
final protected Class<?> _valueClass;
protected StdDeserializer(Class<?> vc) {
_valueClass = vc;
}
protected StdDeserializer(JavaType valueType) {
_valueClass = (valueType == null) ? null : valueType.getRawClass();
}
/**
* Copy-constructor for sub-classes to use, most often when creating
* new instances for {@link com.fasterxml.jackson.databind.deser.ContextualDeserializer}.
*
* @since 2.5
*/
protected StdDeserializer(StdDeserializer<?> src) {
_valueClass = src._valueClass;
}
/*
/**********************************************************
/* Accessors
/**********************************************************
*/
@Override
public Class<?> handledType() { return _valueClass; }
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
/**
* @deprecated Since 2.3 use {@link #handledType} instead
*/
@Deprecated
public final Class<?> getValueClass() { return _valueClass; }
/**
* Exact structured type deserializer handles, if known.
*<p>
* Default implementation just returns null.
*/
public JavaType getValueType() { return null; }
/**
* Method that can be called to determine if given deserializer is the default
* deserializer Jackson uses; as opposed to a custom deserializer installed by
* a module or calling application. Determination is done using
* {@link JacksonStdImpl}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.type;
import java.lang.reflect.*;
import java.util.*;
import com.fasterxml.jackson.databind.JavaType;
/**
* Helper class used for resolving type parameters for given class
*/
public class TypeBindings
{
private final static JavaType[] NO_TYPES = new JavaType[0];
/**
* Marker to use for (temporarily) unbound references.
*/
public final static JavaType UNBOUND = new SimpleType(Object.class);
/**
* Factory to use for constructing resolved related types.
*/
protected final TypeFactory _typeFactory;
/**
* Context type used for resolving all types, if specified. May be null,
* in which case {@link #_contextClass} is used instead.
*/
protected final JavaType _contextType;
/**
* Specific class to use for resolving all types, for methods and fields
* class and its superclasses and -interfaces contain.
*/
protected final Class<?> _contextClass;
/**
* Lazily-instantiated bindings of resolved type parameters
*/
protected Map<String,JavaType> _bindings;
/**
* Also: we may temporarily want to mark certain named types
* as resolved (but without exact type); if so, we'll just store
* names here.
*/
protected HashSet<String> _placeholders;
/**
* Sometimes it is necessary to allow hierarchic resolution of types: specifically
* in cases where there are local bindings (for methods, constructors). If so,
* we'll just use simple delegation model.
*/
private final TypeBindings _parentBindings;
/*
/**********************************************************
/* Construction
/**********************************************************
*/
public TypeBindings(TypeFactory typeFactory, Class<?> cc)
{
this(typeFactory, null, cc, null);
}
public TypeBindings(TypeFactory typeFactory, JavaType type)
{
this(typeFactory, null, type.getRawClass(), type);
}
/**
* Constructor used to create "child" instances; mostly to
* allow delegation from explicitly defined local overrides
* (local type variables for methods, constructors) to
* contextual (class-defined) ones.
*/
public TypeBindings childInstance() {
return new TypeBindings(_typeFactory, this, _contextClass, _contextType);
}
private TypeBindings(TypeFactory tf, TypeBindings parent,
Class<?> cc, JavaType type)
{
_typeFactory = tf;
_parentBindings = parent;
_contextClass = cc;
_contextType = type;
}
/*
/**********************************************************
/* Pass-through type resolution methods
/**********************************************************
*/
public JavaType resolveType(Class<?>
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> cls) {
return _typeFactory._constructType(cls, this);
}
public JavaType resolveType(Type type) {
return _typeFactory._constructType(type, this);
}
/*
/**********************************************************
/* Accesors
/**********************************************************
*/
public int getBindingCount() {
if (_bindings == null) {
_resolve();
}
return _bindings.size();
}
@Deprecated // since 2.6, remove from 2.7
public JavaType findType(String name) {
return findType(name, true);
}
public JavaType findType(String name, boolean mustFind)
{
if (_bindings == null) {
_resolve();
}
JavaType t = _bindings.get(name);
if (t != null) {
return t;
}
if (_placeholders != null && _placeholders.contains(name)) {
return UNBOUND;
}
if (_parentBindings != null) {
return _parentBindings.findType(name);
}
// nothing found, so...
// Should we throw an exception or just return null?
/* [JACKSON-499] 18-Feb-2011, tatu: There are some tricky type bindings within
* java.util, such as HashMap$KeySet; so let's punt the problem
* (honestly not sure what to do -- they are unbound for good, I think)
*/
if (_contextClass != null) {
Class<?> enclosing = _contextClass.getEnclosingClass();
if (enclosing != null) {
// [JACKSON-572]: Actually, let's skip this for all non-static inner classes
// (which will also cover 'java.util' type cases...
if (!Modifier.isStatic(_contextClass.getModifiers())) {
return UNBOUND;
}
// ... so this piece of code should not be needed any more
/*
Package pkg = enclosing.getPackage();
if (pkg != null) {
// as per [JACKSON-533], also include "java.util.concurrent":
if (pkg.getName().startsWith("java.util")) {
return UNBOUND;
}
}
*/
}
}
if (!mustFind) {
return null;
}
String className;
if (_contextClass != null) {
className = _contextClass.getName();
} else if (_contextType != null) {
className = _contextType.toString();
} else {
className = "UNKNOWN";
}
throw new IllegalArgumentException("Type variable '"+name
+"' can not be resolved (with context of class "+className+")");
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
//t = UNBOUND;
}
public void addBinding(String name, JavaType type)
{
// note: emptyMap() is unmodifiable, hence second check is needed:
if (_bindings == null || _bindings.size() == 0) {
_bindings = new LinkedHashMap<String,JavaType>();
}
_bindings.put(name, type);
}
public JavaType[] typesAsArray()
{
if (_bindings == null) {
_resolve();
}
if (_bindings.size() == 0) {
return NO_TYPES;
}
return _bindings.values().toArray(new JavaType[_bindings.size()]);
}
/*
/**********************************************************
/* Internal methods
/**********************************************************
*/
protected void _resolve()
{
_resolveBindings(_contextClass);
// finally: may have root level type info too
if (_contextType != null) {
int count = _contextType.containedTypeCount();
if (count > 0) {
for (int i = 0; i < count; ++i) {
String name = _contextType.containedTypeName(i);
JavaType type = _contextType.containedType(i);
addBinding(name, type);
}
}
}
// nothing bound? mark with empty map to prevent further calls
if (_bindings == null) {
_bindings = Collections.emptyMap();
}
}
public void _addPlaceholder(String name) {
if (_placeholders == null) {
_placeholders = new HashSet<String>();
}
_placeholders.add(name);
}
protected void _resolveBindings(Type t)
{
if (t == null) return;
Class<?> raw;
if (t instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) t;
Type[] args = pt.getActualTypeArguments();
if (args != null && args.length > 0) {
Class<?> rawType = (Class<?>) pt.getRawType();
TypeVariable<?>[] vars = rawType.getTypeParameters();
if (vars.length != args.length) {
throw new IllegalArgumentException("Strange parametrized type (in class "+rawType.getName()+"): number of type arguments != number of type parameters ("+args.length+" vs "+vars.length+")");
}
for (int i = 0, len = args.length; i < len; ++i) {
TypeVariable<?> var = vars[i];
String name = var.getName();
if (_bindings == null) {
_bindings = new LinkedHashMap<String,JavaType>();
} else {
/* 24-Mar-2010, tatu: Better ensure that we
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> do not overwrite something
* collected earlier (since we descend towards super-classes):
*/
if (_bindings.containsKey(name)) continue;
}
// first: add a placeholder to prevent infinite loops
_addPlaceholder(name);
// then resolve type
_bindings.put(name, _typeFactory._constructType(args[i], this));
}
}
raw = (Class<?>)pt.getRawType();
} else if (t instanceof Class<?>) {
raw = (Class<?>) t;
/* [JACKSON-677]: If this is an inner class then the generics are defined on the
* enclosing class so we have to check there as well. We don't
* need to call getEnclosingClass since anonymous classes declare
* generics
*/
Class<?> decl = raw.getDeclaringClass();
/* 08-Feb-2013, tatu: Except that if context is also super-class, we must
* skip it; context will be checked anyway, and we'd get StackOverflow if
* we went there.
*/
if (decl != null && !decl.isAssignableFrom(raw)) {
_resolveBindings(raw.getDeclaringClass());
}
/* 24-Mar-2010, tatu: Can not have true generics definitions, but can
* have lower bounds ("<T extends BeanBase>") in declaration itself
*/
TypeVariable<?>[] vars = raw.getTypeParameters();
if (vars != null && vars.length > 0) {
JavaType[] typeParams = null;
if (_contextType != null && raw.isAssignableFrom(_contextType.getRawClass())) {
typeParams = _typeFactory.findTypeParameters(_contextType, raw);
}
for (int i = 0; i < vars.length; i++) {
TypeVariable<?> var = vars[i];
String name = var.getName();
Type varType = var.getBounds()[0];
if (varType != null) {
if (_bindings == null) {
_bindings = new LinkedHashMap<String,JavaType>();
} else { // and no overwriting...
if (_bindings.containsKey(name)) continue;
}
_addPlaceholder(name); // to prevent infinite loops
if (typeParams != null && typeParams.length > i) {
_bindings.put(name, typeParams[i]);
} else {
_bindings.put(name, _typeFactory._constructType(varType, this));
}
}
}
}
} else { // probably can't be any of these... so let's skip for now
//if (type instanceof GenericArrayType) {
//if (type instanceof TypeVariable
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> = null;
Class<?> prevClass = null;
do {
Object elem = it.next();
if (elem == null) {
provider.defaultSerializeNull(jgen);
continue;
}
JsonSerializer<Object> currSerializer = _elementSerializer;
if (currSerializer == null) {
// Minor optimization to avoid most lookups:
Class<?> cc = elem.getClass();
if (cc == prevClass) {
currSerializer = prevSerializer;
} else {
currSerializer = provider.findValueSerializer(cc, _property);
prevSerializer = currSerializer;
prevClass = cc;
}
}
if (typeSer == null) {
currSerializer.serialize(elem, jgen, provider);
} else {
currSerializer.serializeWithType(elem, jgen, provider, typeSer);
}
} while (it.hasNext());
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.type;
import java.util.*;
import com.fasterxml.jackson.databind.JavaType;
/**
* Type that represents Map-like types; things that consist of key/value pairs but that
* do not necessarily implement {@link java.util.Map}, but that do not have enough
* introspection functionality to allow for some level of generic handling.
* This specifically allows framework to check for configuration and annotation
* settings used for Map types, and pass these to custom handlers that may be more
* familiar with actual type.
*/
public class MapLikeType extends TypeBase
{
private static final long serialVersionUID = 416067702302823522L;
/**
* Type of keys of Map.
*/
protected final JavaType _keyType;
/**
* Type of values of Map.
*/
protected final JavaType _valueType;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
protected MapLikeType(Class<?> mapType, JavaType keyT, JavaType valueT,
Object valueHandler, Object typeHandler, boolean asStatic)
{
super(mapType, keyT.hashCode() ^ valueT.hashCode(), valueHandler, typeHandler, asStatic);
_keyType = keyT;
_valueType = valueT;
}
public static MapLikeType construct(Class<?> rawType, JavaType keyT, JavaType valueT)
{
// nominally component types will be just Object.class
return new MapLikeType(rawType, keyT, valueT, null, null, false);
}
@Override
protected JavaType _narrow(Class<?> subclass) {
return new MapLikeType(subclass, _keyType, _valueType, _valueHandler, _typeHandler, _asStatic);
}
@Override
public JavaType narrowContentsBy(Class<?> contentClass)
{
// Can do a quick check first:
if (contentClass == _valueType.getRawClass()) {
return this;
}
return new MapLikeType(_class, _keyType, _valueType.narrowBy(contentClass),
_valueHandler, _typeHandler, _asStatic);
}
@Override
public JavaType widenContentsBy(Class<?> contentClass)
{
if (contentClass == _valueType.getRawClass()) {
return this;
}
return new MapLikeType(_class, _keyType, _valueType.widenBy(contentClass),
_valueHandler, _typeHandler, _asStatic);
}
public JavaType narrowKey(Class<?> keySubclass)
{
// Can do a quick check first:
if (keySubclass == _keyType.getRaw
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Class()) {
return this;
}
return new MapLikeType(_class, _keyType.narrowBy(keySubclass), _valueType,
_valueHandler, _typeHandler, _asStatic);
}
public JavaType widenKey(Class<?> keySubclass)
{
// Can do a quick check first:
if (keySubclass == _keyType.getRawClass()) {
return this;
}
return new MapLikeType(_class, _keyType.widenBy(keySubclass), _valueType,
_valueHandler, _typeHandler, _asStatic);
}
@Override
public MapLikeType withTypeHandler(Object h)
{
return new MapLikeType(_class, _keyType, _valueType, _valueHandler, h, _asStatic);
}
@Override
public MapLikeType withContentTypeHandler(Object h)
{
return new MapLikeType(_class, _keyType, _valueType.withTypeHandler(h),
_valueHandler, _typeHandler, _asStatic);
}
@Override
public MapLikeType withValueHandler(Object h) {
return new MapLikeType(_class, _keyType, _valueType, h, _typeHandler, _asStatic);
}
@Override
public MapLikeType withContentValueHandler(Object h) {
return new MapLikeType(_class, _keyType, _valueType.withValueHandler(h),
_valueHandler, _typeHandler, _asStatic);
}
@Override
public MapLikeType withStaticTyping() {
if (_asStatic) {
return this;
}
return new MapLikeType(_class, _keyType, _valueType.withStaticTyping(),
_valueHandler, _typeHandler, true);
}
@Override
protected String buildCanonicalName() {
StringBuilder sb = new StringBuilder();
sb.append(_class.getName());
if (_keyType != null) {
sb.append('<');
sb.append(_keyType.toCanonical());
sb.append(',');
sb.append(_valueType.toCanonical());
sb.append('>');
}
return sb.toString();
}
/*
/**********************************************************
/* Public API
/**********************************************************
*/
@Override
public boolean isContainerType() { return true; }
@Override
public boolean isMapLikeType() { return true; }
@Override
public JavaType getKeyType() { return _keyType; }
@Override
public JavaType getContentType() { return _valueType; }
@Override
public int containedTypeCount() { return 2; }
@Override
public JavaType containedType(int index) {
if (index == 0) return _keyType;
if (index == 1) return _
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>valueType;
return null;
}
/**
* Not sure if we should count on this, but type names
* for core interfaces are "K" and "V" respectively.
* For now let's assume this should work.
*/
@Override
public String containedTypeName(int index) {
if (index == 0) return "K";
if (index == 1) return "V";
return null;
}
// TODO: should allow construction of instances that do refer
// to parameterization, since it is NOT Map
@Override
public Class<?> getParameterSource() {
return null;
}
@Override
public StringBuilder getErasedSignature(StringBuilder sb) {
return _classSignature(_class, sb, true);
}
@Override
public StringBuilder getGenericSignature(StringBuilder sb)
{
_classSignature(_class, sb, false);
sb.append('<');
_keyType.getGenericSignature(sb);
_valueType.getGenericSignature(sb);
sb.append(">;");
return sb;
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
public MapLikeType withKeyTypeHandler(Object h)
{
return new MapLikeType(_class, _keyType.withTypeHandler(h), _valueType,
_valueHandler, _typeHandler, _asStatic);
}
public MapLikeType withKeyValueHandler(Object h) {
return new MapLikeType(_class, _keyType.withValueHandler(h), _valueType,
_valueHandler, _typeHandler, _asStatic);
}
/**
* Method that can be used for checking whether this type is a
* "real" Collection type; meaning whether it represents a parameterized
* subtype of {@link java.util.Collection} or just something that acts
* like one.
*/
public boolean isTrueMapType() {
return Map.class.isAssignableFrom(_class);
}
/*
/**********************************************************
/* Standard methods
/**********************************************************
*/
@Override
public String toString()
{
return "[map-like type; class "+_class.getName()+", "+_keyType+" -> "+_valueType+"]";
}
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != getClass()) return false;
MapLikeType other = (MapLikeType) o;
return (_class == other._class)
&& _keyType.equals(other._keyType)
&& _valueType.equals(other._valueType);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.exc;
import java.util.*;
import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonMappingException;
/**
* Specialized {@link JsonMappingException} sub-class used to indicate
* case where an explicitly ignored property is encountered, and mapper
* is configured to consider this an error.
*
* @since 2.3
*/
public class IgnoredPropertyException
extends PropertyBindingException
{
private static final long serialVersionUID = 1L;
public IgnoredPropertyException(String msg, JsonLocation loc,
Class<?> referringClass, String propName,
Collection<Object> propertyIds)
{
super(msg, loc, referringClass, propName, propertyIds);
}
/**
* Factory method used for constructing instances of this exception type.
*
* @param jp Underlying parser used for reading input being used for data-binding
* @param fromObjectOrClass Reference to either instance of problematic type (
* if available), or if not, type itself
* @param propertyName Name of unrecognized property
* @param propertyIds (optional, null if not available) Set of properties that
* type would recognize, if completely known: null if set can not be determined.
*/
public static IgnoredPropertyException from(JsonParser jp,
Object fromObjectOrClass, String propertyName,
Collection<Object> propertyIds)
{
if (fromObjectOrClass == null) {
throw new IllegalArgumentException();
}
Class<?> ref;
if (fromObjectOrClass instanceof Class<?>) {
ref = (Class<?>) fromObjectOrClass;
} else {
ref = fromObjectOrClass.getClass();
}
String msg = "Ignored field \""+propertyName+"\" (class "+ref.getName()
+") encountered; mapper configured not to allow this";
IgnoredPropertyException e = new IgnoredPropertyException(msg,
jp.getCurrentLocation(), ref, propertyName, propertyIds);
// but let's also ensure path includes this last (missing) segment
e.prependPath(fromObjectOrClass, propertyName);
return e;
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.util;
import java.lang.annotation.Annotation;
/**
* Interface that defines interface for accessing contents of a
* collection of annotations. This is needed when introspecting
* annotation-based features from different kinds of things, not
* just objects that Java Reflection interface exposes.
*<p>
* Standard mutable implementation is {@link com.fasterxml.jackson.databind.introspect.AnnotationMap}
*/
public interface Annotations
{
/**
* Main access method used to find value for given annotation.
*/
public <A extends Annotation> A get(Class<A> cls);
/**
* Returns number of annotation entries in this collection.
*/
public int size();
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> can't easily
* change it to be able to move to SerializerProvider (where it
* really belongs)
*/
// 2.1: allow modifications by "id ref" annotations as well:
objectIdInfo = intr.findObjectReferenceInfo(accessor, objectIdInfo);
ObjectIdGenerator<?> gen;
Class<?> implClass = objectIdInfo.getGeneratorType();
JavaType type = provider.constructType(implClass);
JavaType idType = provider.getTypeFactory().findTypeParameters(type, ObjectIdGenerator.class)[0];
// Property-based generator is trickier
if (implClass == ObjectIdGenerators.PropertyGenerator.class) { // most special one, needs extra work
String propName = objectIdInfo.getPropertyName().getSimpleName();
BeanPropertyWriter idProp = null;
for (int i = 0, len = _props.length ;; ++i) {
if (i == len) {
throw new IllegalArgumentException("Invalid Object Id definition for "+_handledType.getName()
+": can not find property with name '"+propName+"'");
}
BeanPropertyWriter prop = _props[i];
if (propName.equals(prop.getName())) {
idProp = prop;
/* Let's force it to be the first property to output
* (although it may still get rearranged etc)
*/
if (i > 0) { // note: must shuffle both regular properties and filtered
System.arraycopy(_props, 0, _props, 1, i);
_props[0] = idProp;
if (_filteredProps != null) {
BeanPropertyWriter fp = _filteredProps[i];
System.arraycopy(_filteredProps, 0, _filteredProps, 1, i);
_filteredProps[0] = fp;
}
}
break;
}
}
idType = idProp.getType();
gen = new PropertyBasedObjectIdGenerator(objectIdInfo, idProp);
oiw = ObjectIdWriter.construct(idType, (PropertyName) null, gen, objectIdInfo.getAlwaysAsId());
} else { // other types need to be simpler
gen = provider.objectIdGeneratorInstance(accessor, objectIdInfo);
oiw = ObjectIdWriter.construct(idType, objectIdInfo.getPropertyName(), gen,
objectIdInfo.getAlwaysAsId());
}
}
// Or change Filter Id in use?
Object filterId = intr.findFilterId(accessor);
if (filterId != null) {
// but only consider case of adding a new filter id (no removal via annotation)
if (_propertyFilterId == null || !filterId.equals(_propertyFilterId)) {
newFilterId = filterId;
}
}
}
//
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> objectWriter() {
return SHARED_MAPPER.writer();
}
protected ObjectReader objectReader() {
return SHARED_MAPPER.reader();
}
protected ObjectReader objectReader(Class<?> cls) {
return SHARED_MAPPER.reader(cls);
}
/*
/**********************************************************
/* Additional assert methods
/**********************************************************
*/
protected void assertEquals(int[] exp, int[] act)
{
assertArrayEquals(exp, act);
}
/**
* Helper method for verifying 3 basic cookie cutter cases;
* identity comparison (true), and against null (false),
* or object of different type (false)
*/
protected void assertStandardEquals(Object o)
{
assertTrue(o.equals(o));
assertFalse(o.equals(null));
assertFalse(o.equals(SINGLETON_OBJECT));
// just for fun, let's also call hash code...
o.hashCode();
}
/*
/**********************************************************
/* Helper methods, serialization
/**********************************************************
*/
@SuppressWarnings("unchecked")
protected Map<String,Object> writeAndMap(ObjectMapper m, Object value)
throws IOException
{
String str = m.writeValueAsString(value);
return (Map<String,Object>) m.readValue(str, Map.class);
}
protected String serializeAsString(ObjectMapper m, Object value)
throws IOException
{
return m.writeValueAsString(value);
}
protected String serializeAsString(Object value)
throws IOException
{
return serializeAsString(SHARED_MAPPER, value);
}
protected String asJSONObjectValueString(Object... args)
throws IOException
{
return asJSONObjectValueString(SHARED_MAPPER, args);
}
protected String asJSONObjectValueString(ObjectMapper m, Object... args)
throws IOException
{
LinkedHashMap<Object,Object> map = new LinkedHashMap<Object,Object>();
for (int i = 0, len = args.length; i < len; i += 2) {
map.put(args[i], args[i+1]);
}
return m.writeValueAsString(map);
}
/*
/**********************************************************
/* Helper methods, deserialization
/**********************************************************
*/
protected <T> T readAndMapFromString(String input, Class<T> cls)
throws IOException
{
return readAndMapFromString(SHARED_MAPPER, input, cls);
}
protected <T> T readAndMapFromString(ObjectMapper m, String input, Class<T> cls) throws IOException
{
return (T) m.readValue("\""+input+"\"", cls);
}
/*
/**********************************************************
/* Helper methods, other
/**********************************************************
*/
protected TimeZone getUTCTimeZone() {
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Handler()) {
return this;
}
return new ArrayType(_componentType.withValueHandler(h), _emptyArray,
_valueHandler, _typeHandler, _asStatic);
}
@Override
public ArrayType withStaticTyping() {
if (_asStatic) {
return this;
}
return new ArrayType(_componentType.withStaticTyping(),
_emptyArray, _valueHandler, _typeHandler, true);
}
@Override
protected String buildCanonicalName() {
return _class.getName();
}
/*
/**********************************************************
/* Methods for narrowing conversions
/**********************************************************
*/
/**
* Handling of narrowing conversions for arrays is trickier: for now,
* it is not even allowed.
*/
@Override
protected JavaType _narrow(Class<?> subclass)
{
/* Ok: need a bit of indirection here. First, must replace component
* type (and check that it is compatible), then re-construct.
*/
if (!subclass.isArray()) { // sanity check, should never occur
throw new IllegalArgumentException("Incompatible narrowing operation: trying to narrow "+toString()+" to class "+subclass.getName());
}
/* Hmmh. This is an awkward back reference... but seems like the
* only simple way to do it.
*/
Class<?> newCompClass = subclass.getComponentType();
/* 14-Mar-2011, tatu: it gets even worse, as we do not have access to
* currently configured TypeFactory. This could theoretically cause
* problems (when narrowing from array of Objects, to array of non-standard
* Maps, for example); but for now need to defer solving this until
* it actually becomes a real problem, not just potential one.
* (famous last words?)
*/
JavaType newCompType = TypeFactory.defaultInstance().constructType(newCompClass);
return construct(newCompType, _valueHandler, _typeHandler);
}
/**
* For array types, both main type and content type can be modified;
* but ultimately they are interchangeable.
*/
@Override
public JavaType narrowContentsBy(Class<?> contentClass)
{
// Can do a quick check first:
if (contentClass == _componentType.getRawClass()) {
return this;
}
return construct(_componentType.narrowBy(contentClass),
_valueHandler, _typeHandler);
}
@Override
public JavaType widenContentsBy(Class<?> contentClass)
{
// Can do a quick check first:
if (contentClass == _componentType.getRawClass()) {
return this;
}
return construct(_componentType.widenBy(contentClass),
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
_valueHandler, _typeHandler);
}
/*
/**********************************************************
/* Overridden methods
/**********************************************************
*/
@Override
public boolean isArrayType() { return true; }
/**
* For some odd reason, modifiers for array classes would
* claim they are abstract types. Not so, at least for our
* purposes.
*/
@Override
public boolean isAbstract() { return false; }
/**
* For some odd reason, modifiers for array classes would
* claim they are abstract types. Not so, at least for our
* purposes.
*/
@Override
public boolean isConcrete() { return true; }
@Override
public boolean hasGenericTypes() {
// arrays are not parameterized, but element type may be:
return _componentType.hasGenericTypes();
}
/**
* Not sure what symbolic name is used internally, if any;
* let's follow naming of Collection types here.
* Should not really matter since array types have no
* super types.
*/
@Override
public String containedTypeName(int index) {
if (index == 0) return "E";
return null;
}
/**
* No parameterization for array types themselves; element type
* may obviously have parameterization.
*/
@Override
public Class<?> getParameterSource() {
return null;
}
/*
/**********************************************************
/* Public API
/**********************************************************
*/
@Override
public boolean isContainerType() { return true; }
@Override
public JavaType getContentType() { return _componentType; }
@Override
public int containedTypeCount() { return 1; }
@Override
public JavaType containedType(int index) {
return (index == 0) ? _componentType : null;
}
@Override
public StringBuilder getGenericSignature(StringBuilder sb) {
sb.append('[');
return _componentType.getGenericSignature(sb);
}
@Override
public StringBuilder getErasedSignature(StringBuilder sb) {
sb.append('[');
return _componentType.getErasedSignature(sb);
}
/*
/**********************************************************
/* Standard methods
/**********************************************************
*/
@Override
public String toString()
{
return "[array type, component type: "+_componentType+"]";
}
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != getClass()) return false;
ArrayType other = (ArrayType) o;
return _componentType.equals(other._componentType);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.annotation;
import java.lang.annotation.*;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
/**
* Annotation that can be used to indicate a {@link PropertyNamingStrategy}
* to use for annotated class. Overrides the global (default) strategy.
*
* @since 2.1
*/
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@com.fasterxml.jackson.annotation.JacksonAnnotation
public @interface JsonNaming
{
/**
* @return Type of {@link PropertyNamingStrategy} to use, if any; default value of
* <code>PropertyNamingStrategy.class</code> means "no strategy specified"
* (and may also be used for overriding to remove otherwise applicable
* naming strategy)
*/
public Class<? extends PropertyNamingStrategy> value() default PropertyNamingStrategy.class;
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind;
import java.lang.annotation.Annotation;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor;
import com.fasterxml.jackson.databind.util.Annotations;
import com.fasterxml.jackson.databind.util.Named;
/**
* Bean properties are logical entities that represent data
* that Java objects (POJOs (Plain Old Java Objects), sometimes also called "beans")
* contain; and that are accessed using accessors (methods like getters
* and setters, fields, constructor parametrers).
* Instances allow access to annotations directly associated
* to property (via field or method), as well as contextual
* annotations (annotations for class that contains properties).
*<p>
* Instances are not typically passed when constructing serializers
* and deserializers, but rather only passed when context
* is known when
* {@link com.fasterxml.jackson.databind.ser.ContextualSerializer} and
* {@link com.fasterxml.jackson.databind.deser.ContextualDeserializer}
* resolution occurs (<code>createContextual(...)</code> method is called).
* References may (need to) be retained by serializers and deserializers,
* especially when further resolving dependant handlers like value
* serializers/deserializers or structured types.
*/
public interface BeanProperty extends Named
{
/**
* Method to get logical name of the property
*/
@Override
public String getName();
/**
* Method for getting full name definition, including possible
* format-specific additional properties (such as namespace when
* using XML backend).
*
* @since 2.3
*/
public PropertyName getFullName();
/**
* Method to get declared type of the property.
*/
public JavaType getType();
/**
* If property is indicated to be wrapped, name of
* wrapper element to use.
*
* @since 2.2
*/
public PropertyName getWrapperName();
/**
* Accessor for additional optional information about property.
*
* @since 2.3
*
* @return Metadata about property; never null.
*/
public PropertyMetadata getMetadata();
/**
* Whether value for property is marked as required using
* annotations or associated schema.
* Equivalent to:
*<code>
* getMetadata().isRequired()
*</code>
*
* @since 2.2
*/
public boolean isRequired();
/**
* Method for finding annotation associated with this property;
* meaning annotation associated with one of entities used to
* access property.
*/
public <A extends Annotation> A getAnnotation(Class<A> acls
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>);
/**
* Method for finding annotation associated with context of
* this property; usually class in which member is declared
* (or its subtype if processing subtype).
*/
public <A extends Annotation> A getContextAnnotation(Class<A> acls);
/**
* Method for accessing primary physical entity that represents the property;
* annotated field, method or constructor property.
*/
public AnnotatedMember getMember();
/**
* Method that can be called to visit the type structure that this
* property is part of.
* Note that not all implementations support traversal with this
* method; those that do not should throw
* {@link UnsupportedOperationException}.
*
* @param objectVisitor Visitor to used as the callback handler
*
* @since 2.2
*/
public void depositSchemaProperty(JsonObjectFormatVisitor objectVisitor)
throws JsonMappingException;
/*
/**********************************************************
/* Helper classes
/**********************************************************
*/
/**
* Simple stand-alone implementation, useful as a placeholder
* or base class for more complex implementations.
*/
public static class Std implements BeanProperty
{
protected final PropertyName _name;
protected final JavaType _type;
protected final PropertyName _wrapperName;
protected final PropertyMetadata _metadata;
/**
* Physical entity (field, method or constructor argument) that
* is used to access value of property (or in case of constructor
* property, just placeholder)
*/
protected final AnnotatedMember _member;
/**
* Annotations defined in the context class (if any); may be null
* if no annotations were found
*/
protected final Annotations _contextAnnotations;
public Std(PropertyName name, JavaType type, PropertyName wrapperName,
Annotations contextAnnotations, AnnotatedMember member,
PropertyMetadata metadata)
{
_name = name;
_type = type;
_wrapperName = wrapperName;
_metadata = metadata;
_member = member;
_contextAnnotations = contextAnnotations;
}
@Deprecated // since 2.3
public Std(String name, JavaType type, PropertyName wrapperName,
Annotations contextAnnotations, AnnotatedMember member,
boolean isRequired)
{
this(new PropertyName(name), type, wrapperName, contextAnnotations,
member,
isRequired ? PropertyMetadata.STD_REQUIRED : PropertyMetadata.STD_OPTIONAL);
}
public Std withType(JavaType type) {
return new Std(_name, type, _wrapperName, _contextAnnotations, _member, _metadata);
}
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return (_member == null) ? null : _member.getAnnotation(acls);
}
@Override
public <A extends Annotation
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>> A getContextAnnotation(Class<A> acls) {
return (_contextAnnotations == null) ? null : _contextAnnotations.get(acls);
}
@Override public String getName() { return _name.getSimpleName(); }
@Override public PropertyName getFullName() { return _name; }
@Override public JavaType getType() { return _type; }
@Override public PropertyName getWrapperName() { return _wrapperName; }
@Override public boolean isRequired() { return _metadata.isRequired(); }
@Override public PropertyMetadata getMetadata() { return _metadata; }
@Override public AnnotatedMember getMember() { return _member; }
/**
*<p>
* TODO: move to {@link BeanProperty} in near future, once all standard
* implementations define it.
*
* @since 2.5
*/
public boolean isVirtual() { return false; }
/**
* Implementation of this method throws
* {@link UnsupportedOperationException}, since instances of this
* implementation should not be used as part of actual structure
* visited. Rather, other implementations should handle it.
*/
@Override
public void depositSchemaProperty(JsonObjectFormatVisitor objectVisitor) {
throw new UnsupportedOperationException("Instances of "+getClass().getName()+" should not get visited");
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind;
import java.lang.reflect.Modifier;
import com.fasterxml.jackson.core.type.ResolvedType;
import com.fasterxml.jackson.databind.type.TypeFactory;
/**
* Base class for type token classes used both to contain information
* and as keys for deserializers.
*<p>
* Instances can (only) be constructed by
* <code>com.fasterxml.jackson.databind.type.TypeFactory</code>.
*<p>
* Since 2.2 this implements {@link java.lang.reflect.Type} to allow
* it to be pushed through interfaces that only expose that type.
*/
public abstract class JavaType
extends ResolvedType
implements java.io.Serializable, // 2.1
java.lang.reflect.Type // 2.2
{
private static final long serialVersionUID = 1;
/**
* This is the nominal type-erased Class that would be close to the
* type represented (but not exactly type, due to type erasure: type
* instance may have more information on this).
* May be an interface or abstract class, so instantiation
* may not be possible.
*/
protected final Class<?> _class;
protected final int _hash;
/**
* Optional handler (codec) that can be attached to indicate
* what to use for handling (serializing, deserializing) values of
* this specific type.
*<p>
* Note: untyped (i.e. caller has to cast) because it is used for
* different kinds of handlers, with unrelated types.
*/
protected final Object _valueHandler;
/**
* Optional handler that can be attached to indicate how to handle
* additional type metadata associated with this type.
*<p>
* Note: untyped (i.e. caller has to cast) because it is used for
* different kinds of handlers, with unrelated types.
*/
protected final Object _typeHandler;
/**
* Whether entities defined with this type should be handled using
* static typing (as opposed to dynamic runtime type) or not.
*
* @since 2.2
*/
protected final boolean _asStatic;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
/**
* @param raw "Raw" (type-erased) class for this type
* @param additionalHash Additional hash code to use, in addition
* to hash code of the class name
*/
protected JavaType(Class<?> raw, int additionalHash,
Object valueHandler, Object typeHandler, boolean asStatic)
{
_class = raw;
_hash = raw.getName().hashCode() + additionalHash;
_valueHandler = value
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Handler;
_typeHandler = typeHandler;
_asStatic = asStatic;
}
/**
* "Copy method" that will construct a new instance that is identical to
* this instance, except that it will have specified type handler assigned.
*
* @return Newly created type instance
*/
public abstract JavaType withTypeHandler(Object h);
/**
* "Copy method" that will construct a new instance that is identical to
* this instance, except that its content type will have specified
* type handler assigned.
*
* @return Newly created type instance
*/
public abstract JavaType withContentTypeHandler(Object h);
/**
* "Copy method" that will construct a new instance that is identical to
* this instance, except that it will have specified value handler assigned.
*
* @return Newly created type instance
*/
public abstract JavaType withValueHandler(Object h);
/**
* "Copy method" that will construct a new instance that is identical to
* this instance, except that it will have specified content value handler assigned.
*
* @return Newly created type instance
*/
public abstract JavaType withContentValueHandler(Object h);
/**
* Method that can be called to get a type instance that indicates
* that values of the type should be handled using "static typing" for purposes
* of serialization (as opposed to "dynamic" aka runtime typing):
* meaning that no runtime information is needed for determining serializers to use.
* The main use case is to allow forcing of specific root value serialization type,
* and specifically in resolving serializers for contained types (element types
* for arrays, Collections and Maps).
*
* @since 2.2
*/
public abstract JavaType withStaticTyping();
/*
/**********************************************************
/* Type coercion fluent factory methods
/**********************************************************
*/
/**
* Method that can be called to do a "narrowing" conversions; that is,
* to return a type with a raw class that is assignable to the raw
* class of this type. If this is not possible, an
* {@link IllegalArgumentException} is thrown.
* If class is same as the current raw class, instance itself is
* returned.
*/
public JavaType narrowBy(Class<?> subclass)
{
// First: if same raw class, just return this instance
if (subclass == _class) { return this; }
// Otherwise, ensure compatibility
_assertSubclass(subclass, _class);
JavaType result = _narrow(subclass);
// TODO: these checks should NOT actually be needed; above should suffice:
if (_valueHandler != result.<Object>getValueHandler()) {
result = result.withValueHandler(_valueHandler);
}
if (_typeHandler != result
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>.<Object>getTypeHandler()) {
result = result.withTypeHandler(_typeHandler);
}
return result;
}
/**
* More efficient version of {@link #narrowBy}, called by
* internal framework in cases where compatibility checks
* are to be skipped.
*/
public JavaType forcedNarrowBy(Class<?> subclass)
{
if (subclass == _class) { // can still optimize for simple case
return this;
}
JavaType result = _narrow(subclass);
// TODO: these checks should NOT actually be needed; above should suffice:
if (_valueHandler != result.<Object>getValueHandler()) {
result = result.withValueHandler(_valueHandler);
}
if (_typeHandler != result.<Object>getTypeHandler()) {
result = result.withTypeHandler(_typeHandler);
}
return result;
}
/**
* Method that can be called to do a "widening" conversions; that is,
* to return a type with a raw class that could be assigned from this
* type.
* If such conversion is not possible, an
* {@link IllegalArgumentException} is thrown.
* If class is same as the current raw class, instance itself is
* returned.
*/
public JavaType widenBy(Class<?> superclass) {
// First: if same raw class, just return this instance
if (superclass == _class) { return this; }
// Otherwise, ensure compatibility
_assertSubclass(_class, superclass);
return _widen(superclass);
}
protected abstract JavaType _narrow(Class<?> subclass);
/**
*<p>
* Default implementation is just to call {@link #_narrow}, since
* underlying type construction is usually identical
*/
protected JavaType _widen(Class<?> superclass) { return _narrow(superclass); }
public abstract JavaType narrowContentsBy(Class<?> contentClass);
public abstract JavaType widenContentsBy(Class<?> contentClass);
/*
/**********************************************************
/* Implementation of ResolvedType API
/**********************************************************
*/
@Override
public final Class<?> getRawClass() { return _class; }
/**
* Method that can be used to check whether this type has
* specified Class as its type erasure. Put another way, returns
* true if instantiation of this Type is given (type-erased) Class.
*/
@Override
public final boolean hasRawClass(Class<?> clz) { return _class == clz; }
@Override
public boolean isAbstract() {
return Modifier.isAbstract(_class.getModifiers());
}
/**
* Convenience method for checking whether underlying Java type
* is a concrete class or not: abstract classes and interfaces
* are not.
*/
@Override
public
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
public abstract Class<?> getParameterSource();
/*
/**********************************************************
/* Extended API beyond ResolvedType
/**********************************************************
*/
// NOTE: not defined in Resolved type
/**
* Convenience method that is functionally same as:
*<code>
* JavaType t = containedType(index);
* if (t == null) {
* t = TypeFactory.unknownType();
* }
*</code>
* and typically used to eliminate need for null checks for common case
* where we just want to check if containedType is available first; and
* if not, use "unknown type" (which translates to <code>java.lang.Object</code>
* basically).
*
* @since 2.5
*/
public JavaType containedTypeOrUnknown(int index) {
JavaType t = containedType(index);
return (t == null) ? TypeFactory.unknownType() : t;
}
/*
/**********************************************************
/* Semi-public API, accessing handlers
/**********************************************************
*/
/**
* Method for accessing value handler associated with this type, if any
*/
@SuppressWarnings("unchecked")
public <T> T getValueHandler() { return (T) _valueHandler; }
/**
* Method for accessing type handler associated with this type, if any
*/
@SuppressWarnings("unchecked")
public <T> T getTypeHandler() { return (T) _typeHandler; }
/*
/**********************************************************
/* Support for producing signatures
/**********************************************************
*/
//public abstract String toCanonical();
/**
* Method for accessing signature that contains generic
* type information, in form compatible with JVM 1.5
* as per JLS. It is a superset of {@link #getErasedSignature},
* in that generic information can be automatically removed
* if necessary (just remove outermost
* angle brackets along with content inside)
*/
public String getGenericSignature() {
StringBuilder sb = new StringBuilder(40);
getGenericSignature(sb);
return sb.toString();
}
/**
*
* @param sb StringBuilder to append signature to
*
* @return StringBuilder that was passed in; returned to allow
* call chaining
*/
public abstract StringBuilder getGenericSignature(StringBuilder sb);
/**
* Method for accessing signature without generic
* type information, in form compatible with all versions
* of JVM, and specifically used for type descriptions
* when generating byte code.
*/
public String getErasedSignature() {
StringBuilder sb = new StringBuilder(40);
getErasedSignature(sb);
return sb.toString();
}
/**
* Method for accessing signature without generic
* type information, in form compatible with all versions
* of JVM, and specifically
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> used for type descriptions
* when generating byte code.
*
* @param sb StringBuilder to append signature to
*
* @return StringBuilder that was passed in; returned to allow
* call chaining
*/
public abstract StringBuilder getErasedSignature(StringBuilder sb);
/*
/**********************************************************
/* Helper methods
/**********************************************************
*/
protected void _assertSubclass(Class<?> subclass, Class<?> superClass) {
if (!_class.isAssignableFrom(subclass)) {
throw new IllegalArgumentException("Class "+subclass.getName()+" is not assignable to "+_class.getName());
}
}
/*
/**********************************************************
/* Standard methods; let's make them abstract to force override
/**********************************************************
*/
@Override
public abstract String toString();
@Override
public abstract boolean equals(Object o);
@Override
public final int hashCode() { return _hash; }
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> Method that can be called to locate value to be injected for this
* property, if it is configured for this.
*/
public Object findInjectableValue(DeserializationContext context, Object beanInstance)
{
if (_injectableValueId == null) {
throw new IllegalStateException("Property '"+getName()
+"' (type "+getClass().getName()+") has no injectable value id configured");
}
return context.findInjectableValue(_injectableValueId, this, beanInstance);
}
/**
* Method to find value to inject, and inject it to this property.
*/
public void inject(DeserializationContext context, Object beanInstance)
throws IOException
{
set(beanInstance, findInjectableValue(context, beanInstance));
}
/*
/**********************************************************
/* BeanProperty impl
/**********************************************************
*/
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
if (_annotated == null) {
return null;
}
return _annotated.getAnnotation(acls);
}
@Override public AnnotatedMember getMember() { return _annotated; }
@Override public int getCreatorIndex() {
return _creatorIndex;
}
/*
/**********************************************************
/* Overridden methods
/**********************************************************
*/
@Override
public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt,
Object instance)
throws IOException, JsonProcessingException
{
set(instance, deserialize(jp, ctxt));
}
@Override
public Object deserializeSetAndReturn(JsonParser jp,
DeserializationContext ctxt, Object instance)
throws IOException, JsonProcessingException
{
return setAndReturn(instance, deserialize(jp, ctxt));
}
@Override
public void set(Object instance, Object value) throws IOException
{
/* Hmmmh. Should we return quietly (NOP), or error?
* Perhaps better to throw an exception, since it's generally an error.
*/
if (_fallbackSetter == null) {
throw new IllegalStateException("No fallback setter/field defined: can not use creator property for "
+getClass().getName());
}
_fallbackSetter.set(instance, value);
}
@Override
public Object setAndReturn(Object instance, Object value) throws IOException
{
if (_fallbackSetter == null) {
throw new IllegalStateException("No fallback setter/field defined: can not use creator property for "
+getClass().getName());
}
return _fallbackSetter.setAndReturn(instance, value);
}
@Override
public Object getInjectableValueId() {
return _injectableValueId;
}
@Override
public String toString() { return "[creator property, name '"+getName()+"'; inject id '"+_injectableValueId+"']"; }
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.impl;
import java.io.IOException;
import java.lang.annotation.Annotation;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.*;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
/**
* Specialized {@link SettableBeanProperty} implementation used
* for virtual property that represents Object Id that is used
* for some POJO types (or properties).
*/
public final class ObjectIdValueProperty
extends SettableBeanProperty
{
private static final long serialVersionUID = 1L;
protected final ObjectIdReader _objectIdReader;
public ObjectIdValueProperty(ObjectIdReader objectIdReader,
PropertyMetadata metadata)
{
super(objectIdReader.propertyName, objectIdReader.getIdType(), metadata,
objectIdReader.getDeserializer());
_objectIdReader = objectIdReader;
}
protected ObjectIdValueProperty(ObjectIdValueProperty src, JsonDeserializer<?> deser)
{
super(src, deser);
_objectIdReader = src._objectIdReader;
}
@Deprecated // since 2.3
protected ObjectIdValueProperty(ObjectIdValueProperty src, PropertyName newName) {
super(src, newName);
_objectIdReader = src._objectIdReader;
}
@Deprecated // since 2.3
protected ObjectIdValueProperty(ObjectIdValueProperty src, String newName) {
this(src, new PropertyName(newName));
}
@Override
public ObjectIdValueProperty withName(PropertyName newName) {
return new ObjectIdValueProperty(this, newName);
}
@Override
public ObjectIdValueProperty withValueDeserializer(JsonDeserializer<?> deser) {
return new ObjectIdValueProperty(this, deser);
}
// // // BeanProperty impl
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return null;
}
@Override public AnnotatedMember getMember() { return null; }
/*
/**********************************************************
/* Deserialization methods
/**********************************************************
*/
@Override
public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt,
Object instance) throws IOException
{
deserializeSetAndReturn(jp, ctxt, instance);
}
@Override
public Object deserializeSetAndReturn(JsonParser jp,
DeserializationContext ctxt, Object instance) throws IOException
{
// note: no null checks (unlike usually); deserializer should fail if one found
Object id = _valueDeserializer.deserialize(jp, ctxt);
ReadableObjectId roid = ctxt.findObjectId(id, _objectIdReader.generator, _objectIdReader.resolver);
roid.bindItem(instance);
// also: may
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.fasterxml.jackson.databind.deser.ValueInstantiator;
/**
* Annotation that can be used to indicate a {@link ValueInstantiator} to use
* for creating instances of specified type.
*/
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@com.fasterxml.jackson.annotation.JacksonAnnotation
public @interface JsonValueInstantiator
{
/**
* @return {@link ValueInstantiator} to use for annotated type
*/
public Class<? extends ValueInstantiator> value();
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind;
import java.lang.reflect.Type;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdResolver;
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.ObjectIdInfo;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.Converter;
/**
* Shared base class for {@link DeserializationContext} and
* {@link SerializerProvider}, context objects passed through data-binding
* process. Designed so that some of implementations can rely on shared
* aspects like access to secondary contextual objects like type factories
* or handler instantiators.
*
* @since 2.2
*/
public abstract class DatabindContext
{
/*
/**********************************************************
/* Generic config access
/**********************************************************
*/
/**
* Accessor to currently active configuration (both per-request configs
* and per-mapper config).
*/
public abstract MapperConfig<?> getConfig();
/**
* Convenience method for accessing serialization view in use (if any); equivalent to:
*<pre>
* getConfig().getAnnotationIntrospector();
*</pre>
*/
public abstract AnnotationIntrospector getAnnotationIntrospector();
/*
/**********************************************************
/* Access to specific config settings
/**********************************************************
*/
/**
* Convenience method for checking whether specified serialization
* feature is enabled or not.
* Shortcut for:
*<pre>
* getConfig().isEnabled(feature);
*</pre>
*/
public final boolean isEnabled(MapperFeature feature) {
return getConfig().isEnabled(feature);
}
/**
* Convenience method for accessing serialization view in use (if any); equivalent to:
*<pre>
* getConfig().canOverrideAccessModifiers();
*</pre>
*/
public final boolean canOverrideAccessModifiers() {
return getConfig().canOverrideAccessModifiers();
}
/**
* Accessor for locating currently active view, if any;
* returns null if no view has been set.
*/
public abstract Class<?> getActiveView();
/*
/**********************************************************
/* Generic attributes (2.3+)
/**********************************************************
*/
/**
* Method for accessing attributes available in this context.
* Per-call attributes have highest precedence; attributes set
* via {@link ObjectReader} or {@link ObjectWriter} have lower
* precedence.
*
* @param key Key of
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> the attribute to get
* @return Value of the attribute, if any; null otherwise
*
* @since 2.3
*/
public abstract Object getAttribute(Object key);
/**
* Method for setting per-call value of given attribute.
* This will override any previously defined value for the
* attribute within this context.
*
* @param key Key of the attribute to set
* @param value Value to set attribute to
*
* @return This context object, to allow chaining
*
* @since 2.3
*/
public abstract DatabindContext setAttribute(Object key, Object value);
/*
/**********************************************************
/* Type instantiation/resolution
/**********************************************************
*/
/**
* Convenience method for constructing {@link JavaType} for given JDK
* type (usually {@link java.lang.Class})
*/
public JavaType constructType(Type type) {
return getTypeFactory().constructType(type);
}
/**
* Convenience method for constructing subtypes, retaining generic
* type parameter (if any)
*/
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) {
// simple optimization to avoid costly introspection if type-erased type does NOT differ
if (baseType.getRawClass() == subclass) {
return baseType;
}
return getConfig().constructSpecializedType(baseType, subclass);
}
public abstract TypeFactory getTypeFactory();
/*
/**********************************************************
/* Helper object construction
/**********************************************************
*/
public ObjectIdGenerator<?> objectIdGeneratorInstance(Annotated annotated,
ObjectIdInfo objectIdInfo)
throws JsonMappingException
{
Class<?> implClass = objectIdInfo.getGeneratorType();
final MapperConfig<?> config = getConfig();
HandlerInstantiator hi = config.getHandlerInstantiator();
ObjectIdGenerator<?> gen = (hi == null) ? null : hi.objectIdGeneratorInstance(config, annotated, implClass);
if (gen == null) {
gen = (ObjectIdGenerator<?>) ClassUtil.createInstance(implClass,
config.canOverrideAccessModifiers());
}
return gen.forScope(objectIdInfo.getScope());
}
public ObjectIdResolver objectIdResolverInstance(Annotated annotated, ObjectIdInfo objectIdInfo)
{
Class<? extends ObjectIdResolver> implClass = objectIdInfo.getResolverType();
final MapperConfig<?> config = getConfig();
HandlerInstantiator hi = config.getHandlerInstantiator();
ObjectIdResolver resolver = (hi == null) ? null : hi.resolverIdGeneratorInstance(config, annotated, implClass);
if (resolver == null) {
resolver = ClassUtil.createInstance(implClass, config.canOverrideAccessModifiers());
}
return resolver;
}
/**
* Helper method to
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> use to construct a {@link Converter}, given a definition
* that may be either actual converter instance, or Class for instantiating one.
*
* @since 2.2
*/
@SuppressWarnings("unchecked")
public Converter<Object,Object> converterInstance(Annotated annotated,
Object converterDef)
throws JsonMappingException
{
if (converterDef == null) {
return null;
}
if (converterDef instanceof Converter<?,?>) {
return (Converter<Object,Object>) converterDef;
}
if (!(converterDef instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector returned Converter definition of type "
+converterDef.getClass().getName()+"; expected type Converter or Class<Converter> instead");
}
Class<?> converterClass = (Class<?>)converterDef;
// there are some known "no class" markers to consider too:
if (converterClass == Converter.None.class || ClassUtil.isBogusClass(converterClass)) {
return null;
}
if (!Converter.class.isAssignableFrom(converterClass)) {
throw new IllegalStateException("AnnotationIntrospector returned Class "
+converterClass.getName()+"; expected Class<Converter>");
}
final MapperConfig<?> config = getConfig();
HandlerInstantiator hi = config.getHandlerInstantiator();
Converter<?,?> conv = (hi == null) ? null : hi.converterInstance(config, annotated, converterClass);
if (conv == null) {
conv = (Converter<?,?>) ClassUtil.createInstance(converterClass,
config.canOverrideAccessModifiers());
}
return (Converter<Object,Object>) conv;
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.impl;
import java.util.*;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ser.SerializerCache.TypeKey;
/**
* Optimized lookup table for accessing two types of serializers; typed
* and non-typed. Only accessed from a single thread, so no synchronization
* needed for accessors.
*/
public final class ReadOnlyClassToSerializerMap
{
/**
* Actual mappings from type key to serializers
*/
protected final JsonSerializerMap _map;
/**
* We'll reuse key class to avoid unnecessary instantiations; since
* this is not shared between threads, we can just reuse single
* instance.
*/
protected TypeKey _cacheKey = null;
private ReadOnlyClassToSerializerMap(JsonSerializerMap map) {
_map = map;
}
public ReadOnlyClassToSerializerMap instance() {
return new ReadOnlyClassToSerializerMap(_map);
}
/**
* Factory method for creating the "blueprint" lookup map. Such map
* can not be used as is but just shared: to get an actual usable
* instance, {@link #instance} has to be called first.
*/
public static ReadOnlyClassToSerializerMap from(HashMap<TypeKey, JsonSerializer<Object>> src) {
return new ReadOnlyClassToSerializerMap(new JsonSerializerMap(src));
}
public JsonSerializer<Object> typedValueSerializer(JavaType type) {
if (_cacheKey == null) {
_cacheKey = new TypeKey(type, true);
} else {
_cacheKey.resetTyped(type);
}
return _map.find(_cacheKey);
}
public JsonSerializer<Object> typedValueSerializer(Class<?> cls) {
if (_cacheKey == null) {
_cacheKey = new TypeKey(cls, true);
} else {
_cacheKey.resetTyped(cls);
}
return _map.find(_cacheKey);
}
public JsonSerializer<Object> untypedValueSerializer(JavaType type) {
if (_cacheKey == null) {
_cacheKey = new TypeKey(type, false);
} else {
_cacheKey.resetUntyped(type);
}
return _map.find(_cacheKey);
}
public JsonSerializer<Object> untypedValueSerializer(Class<?> cls) {
if (_cacheKey == null) {
_cacheKey = new TypeKey(cls, false);
} else {
_cacheKey.resetUntyped(cls);
}
return _map.find(_cacheKey);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
import java.lang.reflect.Type;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
/**
* Simple general purpose serializer, useful for any
* type for which {@link Object#toString} returns the desired JSON
* value.
*/
@JacksonStdImpl
@SuppressWarnings("serial")
public class ToStringSerializer
extends StdSerializer<Object>
{
/**
* Singleton instance to use.
*/
public final static ToStringSerializer instance = new ToStringSerializer();
/**
*<p>
* Note: usually you should NOT create new instances, but instead use
* {@link #instance} which is stateless and fully thread-safe. However,
* there are cases where constructor is needed; for example,
* when using explicit serializer annotations like
* {@link com.fasterxml.jackson.databind.annotation.JsonSerialize#using}.
*/
public ToStringSerializer() { super(Object.class); }
/**
* Sometimes it may actually make sense to retain actual handled type, so...
*
* @since 2.5
*/
public ToStringSerializer(Class<?> handledType) {
super(handledType, false);
}
@Override
@Deprecated
public boolean isEmpty(Object value) {
return isEmpty(null, value);
}
@Override
public boolean isEmpty(SerializerProvider prov, Object value) {
if (value == null) {
return true;
}
String str = value.toString();
return str.isEmpty();
}
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider)
throws IOException
{
gen.writeString(value.toString());
}
/* 01-Mar-2011, tatu: We were serializing as "raw" String; but generally that
* is not what we want, since lack of type information would imply real
* String type.
*/
/**
* Default implementation will write type prefix, call regular serialization
* method (since assumption is that value itself does not need JSON
* Array or Object start/end markers), and then write type suffix.
* This should work for most cases; some sub-classes may want to
* change this
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.impl;
import java.io.IOException;
import java.lang.annotation.Annotation;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.deser.UnresolvedForwardReference;
import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId.Referring;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.ObjectIdInfo;
public class ObjectIdReferenceProperty extends SettableBeanProperty {
private static final long serialVersionUID = 1L;
private final SettableBeanProperty _forward;
public ObjectIdReferenceProperty(SettableBeanProperty forward, ObjectIdInfo objectIdInfo)
{
super(forward);
_forward = forward;
_objectIdInfo = objectIdInfo;
}
public ObjectIdReferenceProperty(ObjectIdReferenceProperty src, JsonDeserializer<?> deser)
{
super(src, deser);
_forward = src._forward;
_objectIdInfo = src._objectIdInfo;
}
public ObjectIdReferenceProperty(ObjectIdReferenceProperty src, PropertyName newName)
{
super(src, newName);
_forward = src._forward;
_objectIdInfo = src._objectIdInfo;
}
@Override
public SettableBeanProperty withValueDeserializer(JsonDeserializer<?> deser) {
return new ObjectIdReferenceProperty(this, deser);
}
@Override
public SettableBeanProperty withName(PropertyName newName) {
return new ObjectIdReferenceProperty(this, newName);
}
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return _forward.getAnnotation(acls);
}
@Override
public AnnotatedMember getMember() {
return _forward.getMember();
}
@Override
public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt, Object instance) throws IOException {
deserializeSetAndReturn(jp, ctxt, instance);
}
@Override
public Object deserializeSetAndReturn(JsonParser jp, DeserializationContext ctxt, Object instance)
throws IOException
{
try {
return setAndReturn(instance, deserialize(jp, ctxt));
} catch (UnresolvedForwardReference reference) {
boolean usingIdentityInfo = (_objectIdInfo != null) || (_valueDeserializer.getObjectIdReader() != null);
if (!usingIdentityInfo) {
throw JsonMappingException.from(jp, "Unresolved forward reference but no identity info.", reference);
}
reference.getRoid().appendReferring(new PropertyReferring(this, reference, _type.getRawClass(), instance
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>));
return null;
}
}
@Override
public void set(Object instance, Object value) throws IOException {
_forward.set(instance, value);
}
@Override
public Object setAndReturn(Object instance, Object value) throws IOException {
return _forward.setAndReturn(instance, value);
}
public final static class PropertyReferring extends Referring {
private final ObjectIdReferenceProperty _parent;
public final Object _pojo;
public PropertyReferring(ObjectIdReferenceProperty parent,
UnresolvedForwardReference ref, Class<?> type, Object ob)
{
super(ref, type);
_parent = parent;
_pojo = ob;
}
@Override
public void handleResolvedForwardReference(Object id, Object value) throws IOException
{
if (!hasId(id)) {
throw new IllegalArgumentException("Trying to resolve a forward reference with id [" + id
+ "] that wasn't previously seen as unresolved.");
}
_parent.set(_pojo, value);
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.fasterxml.jackson.databind.introspect.*;
import com.fasterxml.jackson.databind.type.TypeBindings;
import com.fasterxml.jackson.databind.util.Annotations;
import com.fasterxml.jackson.databind.util.Converter;
/**
* Basic container for information gathered by {@link ClassIntrospector} to
* help in constructing serializers and deserializers.
* Note that the main implementation type is
* {@link com.fasterxml.jackson.databind.introspect.BasicBeanDescription},
* meaning that it is safe to upcast to this type.
*/
public abstract class BeanDescription
{
/*
/**********************************************************
/* Configuration
/**********************************************************
*/
/**
* Bean type information, including raw class and possible
* * generics information
*/
protected final JavaType _type;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
protected BeanDescription(JavaType type) {
_type = type;
}
/*
/**********************************************************
/* Simple accesors
/**********************************************************
*/
/**
* Method for accessing declared type of bean being introspected,
* including full generic type information (from declaration)
*/
public JavaType getType() { return _type; }
public Class<?> getBeanClass() { return _type.getRawClass(); }
/**
* Method for accessing low-level information about Class this
* item describes.
*/
public abstract AnnotatedClass getClassInfo();
/**
* Accessor for getting information about Object Id expected to
* be used for this POJO type, if any.
*/
public abstract ObjectIdInfo getObjectIdInfo();
/**
* Method for checking whether class being described has any
* annotations recognized by registered annotation introspector.
*/
public abstract boolean hasKnownClassAnnotations();
/**
* Accessor for type bindings that may be needed to fully resolve
* types of member object, such as return and argument types of
* methods and constructors, and types of fields.
*/
public abstract TypeBindings bindingsForBeanType();
/**
* Method for resolving given JDK type, using this bean as the
* generic type resolution context.
*/
public abstract JavaType resolveType(java.lang.reflect.Type jdkType);
/**
* Method for accessing collection of annotations the bean
* class has.
*/
public abstract Annotations getClassAnnotations();
/*
/********************************************************
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>**
/* Basic API for finding properties
/**********************************************************
*/
/**
* @return Ordered Map with logical property name as key, and
* matching getter method as value.
*/
public abstract List<BeanPropertyDefinition> findProperties();
/**
* Method for locating all back-reference properties (setters, fields) bean has
*/
public abstract Map<String,AnnotatedMember> findBackReferenceProperties();
public abstract Set<String> getIgnoredPropertyNames();
/*
/**********************************************************
/* Basic API for finding creator members
/**********************************************************
*/
public abstract List<AnnotatedConstructor> getConstructors();
public abstract List<AnnotatedMethod> getFactoryMethods();
/**
* Method that will locate the no-arg constructor for this class,
* if it has one, and that constructor has not been marked as
* ignorable.
*/
public abstract AnnotatedConstructor findDefaultConstructor();
/**
* Method that can be called to locate a single-arg constructor that
* takes specified exact type (will not accept supertype constructors)
*
* @param argTypes Type(s) of the argument that we are looking for
*/
public abstract Constructor<?> findSingleArgConstructor(Class<?>... argTypes);
/**
* Method that can be called to find if introspected class declares
* a static "valueOf" factory method that returns an instance of
* introspected type, given one of acceptable types.
*
* @param expArgTypes Types that the matching single argument factory
* method can take: will also accept super types of these types
* (ie. arg just has to be assignable from expArgType)
*/
public abstract Method findFactoryMethod(Class<?>... expArgTypes);
/*
/**********************************************************
/* Basic API for finding property accessors
/**********************************************************
*/
public abstract AnnotatedMember findAnyGetter();
/**
* Method used to locate the method of introspected class that
* implements {@link com.fasterxml.jackson.annotation.JsonAnySetter}. If no such method exists
* null is returned. If more than one are found, an exception
* is thrown.
* Additional checks are also made to see that method signature
* is acceptable: needs to take 2 arguments, first one String or
* Object; second any can be any type.
*/
public abstract AnnotatedMethod findAnySetter();
/**
* Method for locating the getter method that is annotated with
* {@link com.fasterxml.jackson.annotation.JsonValue} annotation,
* if any. If multiple ones are found,
* an error is reported by throwing {@link IllegalArgumentException}
*/
public abstract AnnotatedMethod findJsonValueMethod();
public abstract AnnotatedMethod findMethod(String name, Class<?>[] paramTypes);
/*
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> /**********************************************************
/* Basic API, class configuration
/**********************************************************
*/
public abstract JsonInclude.Include findSerializationInclusion(JsonInclude.Include defValue);
/**
* @since 2.5
*/
public abstract JsonInclude.Include findSerializationInclusionForContent(JsonInclude.Include defValue);
/**
* Method for checking what is the expected format for POJO, as
* defined by defaults and possible annotations.
* Note that this may be further refined by per-property annotations.
*
* @since 2.1
*/
public abstract JsonFormat.Value findExpectedFormat(JsonFormat.Value defValue);
/**
* Method for finding {@link Converter} used for serializing instances
* of this class.
*
* @since 2.2
*/
public abstract Converter<Object,Object> findSerializationConverter();
/**
* Method for finding {@link Converter} used for serializing instances
* of this class.
*
* @since 2.2
*/
public abstract Converter<Object,Object> findDeserializationConverter();
/*
/**********************************************************
/* Basic API, other
/**********************************************************
*/
public abstract Map<Object, AnnotatedMember> findInjectables();
/**
* Method for checking if the POJO type has annotations to
* indicate that a builder is to be used for instantiating
* instances and handling data binding, instead of standard
* bean deserializer.
*/
public abstract Class<?> findPOJOBuilder();
/**
* Method for finding configuration for POJO Builder class.
*/
public abstract JsonPOJOBuilder.Value findPOJOBuilderConfig();
/**
* Method called to create a "default instance" of the bean, currently
* only needed for obtaining default field values which may be used for
* suppressing serialization of fields that have "not changed".
*
* @param fixAccess If true, method is allowed to fix access to the
* default constructor (to be able to call non-public constructor);
* if false, has to use constructor as is.
*
* @return Instance of class represented by this descriptor, if
* suitable default constructor was found; null otherwise.
*/
public abstract Object instantiateBean(boolean fixAccess);
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
ser = provider.handleSecondaryContextualization(ser, property);
}
return withResolved(property, vts, ser);
}
/*
/**********************************************************
/* Accessors
/**********************************************************
*/
@Override
public JavaType getContentType() {
return _elementType;
}
@Override
public JsonSerializer<?> getContentSerializer() {
return _elementSerializer;
}
@Override
public boolean isEmpty(SerializerProvider prov, Object[] value) {
return (value == null) || (value.length == 0);
}
@Override
public boolean hasSingleElement(Object[] value) {
return (value.length == 1);
}
/*
/**********************************************************
/* Actual serialization
/**********************************************************
*/
@Override
public final void serialize(Object[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException
{
final int len = value.length;
if ((len == 1) && provider.isEnabled(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED)) {
serializeContents(value, jgen, provider);
return;
}
jgen.writeStartArray(len);
serializeContents(value, jgen, provider);
jgen.writeEndArray();
}
@Override
public void serializeContents(Object[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException
{
final int len = value.length;
if (len == 0) {
return;
}
if (_elementSerializer != null) {
serializeContentsUsing(value, jgen, provider, _elementSerializer);
return;
}
if (_valueTypeSerializer != null) {
serializeTypedContents(value, jgen, provider);
return;
}
int i = 0;
Object elem = null;
try {
PropertySerializerMap serializers = _dynamicSerializers;
for (; i < len; ++i) {
elem = value[i];
if (elem == null) {
provider.defaultSerializeNull(jgen);
continue;
}
Class<?> cc = elem.getClass();
JsonSerializer<Object> serializer = serializers.serializerFor(cc);
if (serializer == null) {
// To fix [JACKSON-508]
if (_elementType.hasGenericTypes()) {
serializer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_elementType, cc), provider);
} else {
serializer = _findAndAddDynamic(serializers, cc, provider);
}
}
serializer.serialize(elem, jgen, provider);
}
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
// [JACKSON-55] Need to add reference information
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
/* 05-Mar-2009, tatu: But one nasty edge is when we get
* StackOverflow: usually due to infinite loop. But that gets
* hidden within an InvocationTargetException...
*/
Throwable t = e;
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
if (t instanceof Error) {
throw (Error) t;
}
throw JsonMappingException.wrapWithPath(t, elem, i);
}
}
public void serializeContentsUsing(Object[] value, JsonGenerator jgen, SerializerProvider provider,
JsonSerializer<Object> ser) throws IOException
{
final int len = value.length;
final TypeSerializer typeSer = _valueTypeSerializer;
int i = 0;
Object elem = null;
try {
for (; i < len; ++i) {
elem = value[i];
if (elem == null) {
provider.defaultSerializeNull(jgen);
continue;
}
if (typeSer == null) {
ser.serialize(elem, jgen, provider);
} else {
ser.serializeWithType(elem, jgen, provider, typeSer);
}
}
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
Throwable t = e;
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
if (t instanceof Error) {
throw (Error) t;
}
throw JsonMappingException.wrapWithPath(t, elem, i);
}
}
public void serializeTypedContents(Object[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException
{
final int len = value.length;
final TypeSerializer typeSer = _valueTypeSerializer;
int i = 0;
Object elem = null;
try {
PropertySerializerMap serializers = _dynamicSerializers;
for (; i < len; ++i) {
elem = value[i];
if (elem == null) {
provider.defaultSerializeNull(jgen);
continue;
}
Class<?> cc = elem.getClass();
JsonSerializer<Object> serializer = serializers.serializerFor(cc);
if (serializer == null) {
serializer = _findAndAddDynamic(serializers, cc, provider);
}
serializer.serializeWithType(elem, jgen, provider, typeSer);
}
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
Throwable t = e;
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
if
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> (t instanceof Error) {
throw (Error) t;
}
throw JsonMappingException.wrapWithPath(t, elem, i);
}
}
@SuppressWarnings("deprecation")
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint)
throws JsonMappingException
{
ObjectNode o = createSchemaNode("array", true);
if (typeHint != null) {
JavaType javaType = provider.constructType(typeHint);
if (javaType.isArrayType()) {
Class<?> componentType = ((ArrayType) javaType).getContentType().getRawClass();
// 15-Oct-2010, tatu: We can't serialize plain Object.class; but what should it produce here? Untyped?
if (componentType == Object.class) {
o.put("items", com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode());
} else {
JsonSerializer<Object> ser = provider.findValueSerializer(componentType, _property);
JsonNode schemaNode = (ser instanceof SchemaAware) ?
((SchemaAware) ser).getSchema(provider, null) :
com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode();
o.put("items", schemaNode);
}
}
}
return o;
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
throws JsonMappingException
{
JsonArrayFormatVisitor arrayVisitor = visitor.expectArrayFormat(typeHint);
if (arrayVisitor != null) {
TypeFactory tf = visitor.getProvider().getTypeFactory();
JavaType contentType = tf.moreSpecificType(_elementType, typeHint.getContentType());
if (contentType == null) {
throw new JsonMappingException("Could not resolve type");
}
JsonSerializer<?> valueSer = _elementSerializer;
if (valueSer == null) {
valueSer = visitor.getProvider().findValueSerializer(contentType, _property);
}
arrayVisitor.itemsFormat(valueSer, contentType);
}
}
protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
Class<?> type, SerializerProvider provider) throws JsonMappingException
{
PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property);
// did we get a new map of serializers? If so, start using it
if (map != result.map) {
_dynamicSerializers = result.map;
}
return result.serializer;
}
protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
JavaType type, SerializerProvider provider) throws JsonMappingException
{
PropertySerializerMap.SerializerAnd
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonIntegerFormatVisitor;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonNumberFormatVisitor;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
/**
* Container class for serializers used for handling standard JDK-provided types.
*/
@SuppressWarnings("serial")
public class NumberSerializers
{
protected NumberSerializers() { }
public static void addAll(Map<String, JsonSerializer<?>> allDeserializers)
{
final JsonSerializer<?> intS = new IntegerSerializer();
allDeserializers.put(Integer.class.getName(), intS);
allDeserializers.put(Integer.TYPE.getName(), intS);
allDeserializers.put(Long.class.getName(), LongSerializer.instance);
allDeserializers.put(Long.TYPE.getName(), LongSerializer.instance);
allDeserializers.put(Byte.class.getName(), IntLikeSerializer.instance);
allDeserializers.put(Byte.TYPE.getName(), IntLikeSerializer.instance);
allDeserializers.put(Short.class.getName(), ShortSerializer.instance);
allDeserializers.put(Short.TYPE.getName(), ShortSerializer.instance);
// Numbers, limited length floating point
allDeserializers.put(Float.class.getName(), FloatSerializer.instance);
allDeserializers.put(Float.TYPE.getName(), FloatSerializer.instance);
allDeserializers.put(Double.class.getName(), DoubleSerializer.instance);
allDeserializers.put(Double.TYPE.getName(), DoubleSerializer.instance);
}
/*
/**********************************************************
/* Shared base class
/**********************************************************
*/
protected abstract static class Base<T> extends StdScalarSerializer<T>
implements ContextualSerializer
{
protected final JsonParser.NumberType _numberType;
protected final String _schemaType;
protected final boolean _isInt;
protected Base(Class<T> cls, JsonParser.NumberType numberType, String schemaType) {
super(cls);
_numberType = numberType;
_schemaType =
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.KeyDeserializer;
import com.fasterxml.jackson.databind.util.Converter;
/**
* Annotation use for configuring deserialization aspects, by attaching
* to "setter" methods or fields, or to value classes.
* When annotating value classes, configuration is used for instances
* of the value class but can be overridden by more specific annotations
* (ones that attach to methods or fields).
*<p>
* An example annotation would be:
*<pre>
* @JsonDeserialize(using=MySerializer.class,
* as=MyHashMap.class,
* keyAs=MyHashKey.class,
* contentAs=MyHashValue.class
* )
*</pre>
*<p>
*/
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@com.fasterxml.jackson.annotation.JacksonAnnotation
public @interface JsonDeserialize
{
// // // Annotations for explicitly specifying deserialize/builder
/**
* Deserializer class to use for deserializing associated value.
* Depending on what is annotated,
* value is either an instance of annotated class (used globablly
* anywhere where class deserializer is needed); or only used for
* deserializing property access via a setter method.
*/
public Class<? extends JsonDeserializer<?>> using()
default JsonDeserializer.None.class;
/**
* Deserializer class to use for deserializing contents (elements
* of a Collection/array, values of Maps) of annotated property.
* Can only be used on instances (methods, fields, constructors),
* and not value classes themselves.
*/
public Class<? extends JsonDeserializer<?>> contentUsing()
default JsonDeserializer.None.class;
/**
* Deserializer class to use for deserializing Map keys
* of annotated property.
* Can only be used on instances (methods, fields, constructors),
* and not value classes themselves.
*/
public Class<? extends KeyDeserializer> keyUsing()
default KeyDeserializer.None.class;
/**
* Annotation for specifying if an external Builder class is to
* be used for building up deserialized instances of annotated
* class. If so, an instance of referenced class is first constructed
* (possibly using a Creator method; or if none defined, using default
* constructor), and its "
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>with-methods" are used for populating fields;
* and finally "build-method" is invoked to complete deserialization.
*/
public Class<?> builder() default Void.class;
// // // Annotations for specifying intermediate Converters (2.2+)
/**
* Which helper object (if any) is to be used to convert from Jackson-bound
* intermediate type (source type of converter) into actual property type
* (which must be same as result type of converter). This is often used
* for two-step deserialization; Jackson binds data into suitable intermediate
* type (like Tree representation), and converter then builds actual property
* type.
*
* @since 2.2
*/
public Class<? extends Converter<?,?>> converter() default Converter.None.class;
/**
* Similar to {@link #converter}, but used for values of structures types
* (List, arrays, Maps).
*
* @since 2.2
*/
public Class<? extends Converter<?,?>> contentConverter() default Converter.None.class;
// // // Annotations for explicitly specifying deserialization type
// // // (which is used for choosing deserializer, if not explicitly
// // // specified
/**
* Concrete type to deserialize values as, instead of type otherwise
* declared. Must be a subtype of declared type; otherwise an
* exception may be thrown by deserializer.
*<p>
* Bogus type {@link Void} can be used to indicate that declared
* type is used as is (i.e. this annotation property has no setting);
* this since annotation properties are not allowed to have null value.
*<p>
* Note: if {@link #using} is also used it has precedence
* (since it directly specified
* deserializer, whereas this would only be used to locate the
* deserializer)
* and value of this annotation property is ignored.
*/
public Class<?> as() default Void.class;
/**
* Concrete type to deserialize keys of {@link java.util.Map} as,
* instead of type otherwise declared.
* Must be a subtype of declared type; otherwise an exception may be
* thrown by deserializer.
*/
public Class<?> keyAs() default Void.class;
/**
* Concrete type to deserialize content (elements
* of a Collection/array, values of Maps) values as,
* instead of type otherwise declared.
* Must be a subtype of declared type; otherwise an exception may be
* thrown by deserializer.
*/
public Class<?> contentAs() default Void.class;
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.type;
/**
* Key class, used as an efficient and accurate key
* for locating per-class values, such as
* {@link com.fasterxml.jackson.databind.JsonSerializer}s.
*<p>
* The reason for having a separate key class instead of
* directly using {@link Class} as key is mostly
* to allow for redefining <code>hashCode</code> method --
* for some strange reason, {@link Class} does not
* redefine {@link Object#hashCode} and thus uses identity
* hash, which is pretty slow. This makes key access using
* {@link Class} unnecessarily slow.
*<p>
* Note: since class is not strictly immutable, caller must
* know what it is doing, if changing field values.
*/
public final class ClassKey
implements Comparable<ClassKey>,
java.io.Serializable // since 2.1
{
private static final long serialVersionUID = 1L;
private String _className;
private Class<?> _class;
/**
* Let's cache hash code straight away, since we are
* almost certain to need it.
*/
private int _hashCode;
public ClassKey()
{
_class = null;
_className = null;
_hashCode = 0;
}
public ClassKey(Class<?> clz)
{
_class = clz;
_className = clz.getName();
_hashCode = _className.hashCode();
}
public void reset(Class<?> clz)
{
_class = clz;
_className = clz.getName();
_hashCode = _className.hashCode();
}
/*
/**********************************************************
/* Comparable
/**********************************************************
*/
@Override
public int compareTo(ClassKey other)
{
// Just need to sort by name, ok to collide (unless used in TreeMap/Set!)
return _className.compareTo(other._className);
}
/*
/**********************************************************
/* Standard methods
/**********************************************************
*/
@Override
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != getClass()) return false;
ClassKey other = (ClassKey) o;
/* Is it possible to have different Class object for same name + class loader combo?
* Let's assume answer is no: if this is wrong, will need to uncomment following functionality
*/
/*
return (other._className.equals(_className))
&& (other._class.getClassLoader() == _class.getClassLoader());
*/
return other._class == _class;
}
@Override public int hashCode() { return
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.impl;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.util.Annotations;
/**
* This concrete sub-class implements property that is set
* directly assigning to a Field.
*/
public final class FieldProperty
extends SettableBeanProperty
{
private static final long serialVersionUID = 1L;
final protected AnnotatedField _annotated;
/**
* Actual field to set when deserializing this property.
* Transient since there is no need to persist; only needed during
* construction of objects.
*/
final protected transient Field _field;
public FieldProperty(BeanPropertyDefinition propDef, JavaType type,
TypeDeserializer typeDeser, Annotations contextAnnotations, AnnotatedField field)
{
super(propDef, type, typeDeser, contextAnnotations);
_annotated = field;
_field = field.getAnnotated();
}
protected FieldProperty(FieldProperty src, JsonDeserializer<?> deser) {
super(src, deser);
_annotated = src._annotated;
_field = src._field;
}
protected FieldProperty(FieldProperty src, PropertyName newName) {
super(src, newName);
_annotated = src._annotated;
_field = src._field;
}
/**
* Constructor used for JDK Serialization when reading persisted object
*/
protected FieldProperty(FieldProperty src)
{
super(src);
_annotated = src._annotated;
Field f = _annotated.getAnnotated();
if (f == null) {
throw new IllegalArgumentException("Missing field (broken JDK (de)serialization?)");
}
_field = f;
}
@Override
public FieldProperty withName(PropertyName newName) {
return new FieldProperty(this, newName);
}
@Override
public FieldProperty withValueDeserializer(JsonDeserializer<?> deser) {
return new FieldProperty(this, deser);
}
/*
/**********************************************************
/* BeanProperty impl
/**********************************************************
*/
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls) {
return _annotated.getAnnotation(acls);
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.introspect;
import java.lang.reflect.Method;
import java.util.*;
/**
* Simple helper class used to keep track of collection of
* {@link AnnotatedMethod}s, accessible by lookup. Lookup
* is usually needed for augmenting and overriding annotations.
*/
public final class AnnotatedMethodMap
implements Iterable<AnnotatedMethod>
{
protected LinkedHashMap<MemberKey,AnnotatedMethod> _methods;
public AnnotatedMethodMap() { }
/**
* Method called to add specified annotated method in the Map.
*/
public void add(AnnotatedMethod am)
{
if (_methods == null) {
_methods = new LinkedHashMap<MemberKey,AnnotatedMethod>();
}
_methods.put(new MemberKey(am.getAnnotated()), am);
}
/**
* Method called to remove specified method, assuming
* it exists in the Map
*/
public AnnotatedMethod remove(AnnotatedMethod am)
{
return remove(am.getAnnotated());
}
public AnnotatedMethod remove(Method m)
{
if (_methods != null) {
return _methods.remove(new MemberKey(m));
}
return null;
}
public boolean isEmpty() {
return (_methods == null || _methods.size() == 0);
}
public int size() {
return (_methods == null) ? 0 : _methods.size();
}
public AnnotatedMethod find(String name, Class<?>[] paramTypes)
{
if (_methods == null) {
return null;
}
return _methods.get(new MemberKey(name, paramTypes));
}
public AnnotatedMethod find(Method m)
{
if (_methods == null) {
return null;
}
return _methods.get(new MemberKey(m));
}
/*
/**********************************************************
/* Iterable implementation (for iterating over values)
/**********************************************************
*/
@Override
public Iterator<AnnotatedMethod> iterator()
{
if (_methods != null) {
return _methods.values().iterator();
}
List<AnnotatedMethod> empty = Collections.emptyList();
return empty.iterator();
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.impl;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
// Simple placeholder
public class PropertyBasedObjectIdGenerator
extends ObjectIdGenerators.PropertyGenerator
{
private static final long serialVersionUID = 1L;
public PropertyBasedObjectIdGenerator(Class<?> scope) {
super(scope);
}
@Override
public Object generateId(Object forPojo) {
throw new UnsupportedOperationException();
}
@Override
public ObjectIdGenerator<Object> forScope(Class<?> scope) {
return (scope == _scope) ? this : new PropertyBasedObjectIdGenerator(scope);
}
@Override
public ObjectIdGenerator<Object> newForSerialization(Object context) {
return this;
}
@Override
public com.fasterxml.jackson.annotation.ObjectIdGenerator.IdKey key(Object key) {
// should we use general type for all; or type of property itself?
return new IdKey(getClass(), _scope, key);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.impl;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.databind.introspect.ObjectIdInfo;
import com.fasterxml.jackson.databind.ser.*;
public class PropertyBasedObjectIdGenerator
extends ObjectIdGenerators.PropertyGenerator
{
private static final long serialVersionUID = 1L;
protected final BeanPropertyWriter _property;
public PropertyBasedObjectIdGenerator(ObjectIdInfo oid, BeanPropertyWriter prop)
{
this(oid.getScope(), prop);
}
protected PropertyBasedObjectIdGenerator(Class<?> scope, BeanPropertyWriter prop)
{
super(scope);
_property = prop;
}
/**
* We must override this method, to prevent errors when scopes are the same,
* but underlying class (on which to access property) is different.
*/
@Override
public boolean canUseFor(ObjectIdGenerator<?> gen) {
if (gen.getClass() == getClass()) {
PropertyBasedObjectIdGenerator other = (PropertyBasedObjectIdGenerator) gen;
if (other.getScope() == _scope) {
/* 26-Jul-2012, tatu: This is actually not enough, because the property
* accessor within BeanPropertyWriter won't work for other property fields
* (see [https://github.com/FasterXML/jackson-module-jaxb-annotations/issues/9]
* for details).
* So we need to verify that underlying property is actually the same.
*/
return (other._property == _property);
}
}
return false;
}
@Override
public Object generateId(Object forPojo) {
try {
return _property.get(forPojo);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new IllegalStateException("Problem accessing property '"
+_property.getName()+"': "+e.getMessage(), e);
}
}
@Override
public ObjectIdGenerator<Object> forScope(Class<?> scope) {
return (scope == _scope) ? this : new PropertyBasedObjectIdGenerator(scope, _property);
}
@Override
public ObjectIdGenerator<Object> newForSerialization(Object context) {
// No state, can return this
return this;
}
@Override
public com.fasterxml.jackson.annotation.ObjectIdGenerator.IdKey key(Object key) {
// should we use general type for all; or type of property itself?
return new IdKey(getClass(), _scope, key);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>ser == null) {
Class<?> cls = value.getClass();
PropertySerializerMap map = _dynamicSerializers;
ser = map.serializerFor(cls);
if (ser == null) {
ser = _findAndAddDynamic(map, cls, prov);
}
}
if (_suppressableValue != null) {
if (MARKER_FOR_EMPTY == _suppressableValue) {
if (ser.isEmpty(prov, value)) {
return;
}
} else if (_suppressableValue.equals(value)) {
return;
}
}
// For non-nulls, first: simple check for direct cycles
if (value == bean) {
if (_handleSelfReference(bean, jgen, prov, ser)) {
return;
}
}
// note: must verify we are using unwrapping serializer; if not, will write field name
if (!ser.isUnwrappingSerializer()) {
jgen.writeFieldName(_name);
}
if (_typeSerializer == null) {
ser.serialize(value, jgen, prov);
} else {
ser.serializeWithType(value, jgen, prov, _typeSerializer);
}
}
// need to override as we must get unwrapping instance...
@Override
public void assignSerializer(JsonSerializer<Object> ser)
{
super.assignSerializer(ser);
if (_serializer != null) {
NameTransformer t = _nameTransformer;
if (_serializer.isUnwrappingSerializer()) {
t = NameTransformer.chainedTransformer(t, ((UnwrappingBeanSerializer) _serializer)._nameTransformer);
}
_serializer = _serializer.unwrappingSerializer(t);
}
}
/*
/**********************************************************
/* Overrides: schema generation
/**********************************************************
*/
@Override
public void depositSchemaProperty(final JsonObjectFormatVisitor visitor)
throws JsonMappingException {
SerializerProvider provider = visitor.getProvider();
JsonSerializer<Object> ser = provider
.findValueSerializer(this.getType(), this)
.unwrappingSerializer(_nameTransformer);
if (ser.isUnwrappingSerializer()) {
ser.acceptJsonFormatVisitor(new JsonFormatVisitorWrapper.Base(provider) {
// an unwrapping serializer will always expect ObjectFormat,
// hence, the other cases do not have to be implemented
@Override
public JsonObjectFormatVisitor expectObjectFormat(JavaType type)
throws JsonMappingException {
return visitor;
}
}, this.getType());
} else {
super.depositSchemaProperty(visitor);
}
}
// Override needed to support legacy JSON Schema generator
@Override
protected void _depositSchemaProperty(ObjectNode propertiesNode, JsonNode schemaNode)
{
JsonNode props = schemaNode.get("properties");
if (
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>props != null) {
Iterator<Entry<String, JsonNode>> it = props.fields();
while (it.hasNext()) {
Entry<String,JsonNode> entry = it.next();
String name = entry.getKey();
if (_nameTransformer != null) {
name = _nameTransformer.transform(name);
}
propertiesNode.set(name, entry.getValue());
}
}
}
/*
/**********************************************************
/* Overrides: internal, other
/**********************************************************
*/
// need to override as we must get unwrapping instance...
@Override
protected JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
Class<?> type, SerializerProvider provider) throws JsonMappingException
{
JsonSerializer<Object> serializer;
if (_nonTrivialBaseType != null) {
JavaType subtype = provider.constructSpecializedType(_nonTrivialBaseType, type);
serializer = provider.findValueSerializer(subtype, this);
} else {
serializer = provider.findValueSerializer(type, this);
}
NameTransformer t = _nameTransformer;
if (serializer.isUnwrappingSerializer()) {
t = NameTransformer.chainedTransformer(t, ((UnwrappingBeanSerializer) serializer)._nameTransformer);
}
serializer = serializer.unwrappingSerializer(t);
_dynamicSerializers = _dynamicSerializers.newWith(type, serializer);
return serializer;
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
protected final HashMap<ClassKey,Class<?>> _mixInAnnotations;
/*
/**********************************************************
/* Configuration settings, serialization
/**********************************************************
*/
/**
* Configuration object that defines basic global
* settings for the serialization process
*/
protected SerializationConfig _serializationConfig;
/**
* Object that manages access to serializers used for serialization,
* including caching.
* It is configured with {@link #_serializerFactory} to allow
* for constructing custom serializers.
*<p>
* Note: while serializers are only exposed {@link SerializerProvider},
* mappers and readers need to access additional API defined by
* {@link DefaultSerializerProvider}
*/
protected DefaultSerializerProvider _serializerProvider;
/**
* Serializer factory used for constructing serializers.
*/
protected SerializerFactory _serializerFactory;
/*
/**********************************************************
/* Configuration settings, deserialization
/**********************************************************
*/
/**
* Configuration object that defines basic global
* settings for the serialization process
*/
protected DeserializationConfig _deserializationConfig;
/**
* Blueprint context object; stored here to allow custom
* sub-classes. Contains references to objects needed for
* deserialization construction (cache, factory).
*/
protected DefaultDeserializationContext _deserializationContext;
/*
/**********************************************************
/* Module-related
/**********************************************************
*/
/**
* Set of module types (as per {@link Module#getTypeId()} that have been
* registered; kept track of iff {@link MapperFeature#IGNORE_DUPLICATE_MODULE_REGISTRATIONS}
* is enabled, so that duplicate registration calls can be ignored
* (to avoid adding same handlers multiple times, mostly).
*
* @since 2.5
*/
protected Set<Object> _registeredModuleTypes;
/*
/**********************************************************
/* Caching
/**********************************************************
*/
/* Note: handling of serializers and deserializers is not symmetric;
* and as a result, only root-level deserializers can be cached here.
* This is mostly because typing and resolution for deserializers is
* fully static; whereas it is quite dynamic for serialization.
*/
/**
* We will use a separate main-level Map for keeping track
* of root-level deserializers. This is where most successful
* cache lookups get resolved.
* Map will contain resolvers for all kinds of types, including
* container types: this is different from the component cache
* which will only cache bean deserializers.
*<p>
* Given that we don't expect much concurrency for additions
* (should very quickly converge to zero after startup), let's
* explicitly define a low concurrency setting.
*<p>
* Since version 1.5, these may are either "raw" deserializers (when
* no type information is needed
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> for base type), or type-wrapped
* deserializers (if it is needed)
*/
final protected ConcurrentHashMap<JavaType, JsonDeserializer<Object>> _rootDeserializers
= new ConcurrentHashMap<JavaType, JsonDeserializer<Object>>(64, 0.6f, 2);
/*
/**********************************************************
/* Life-cycle: constructing instance
/**********************************************************
*/
/**
* Default constructor, which will construct the default
* {@link JsonFactory} as necessary, use
* {@link SerializerProvider} as its
* {@link SerializerProvider}, and
* {@link BeanSerializerFactory} as its
* {@link SerializerFactory}.
* This means that it
* can serialize all standard JDK types, as well as regular
* Java Beans (based on method names and Jackson-specific annotations),
* but does not support JAXB annotations.
*/
public ObjectMapper() {
this(null, null, null);
}
/**
* Constructs instance that uses specified {@link JsonFactory}
* for constructing necessary {@link JsonParser}s and/or
* {@link JsonGenerator}s.
*/
public ObjectMapper(JsonFactory jf) {
this(jf, null, null);
}
/**
* Copy-constructor, mostly used to support {@link #copy}.
*
* @since 2.1
*/
protected ObjectMapper(ObjectMapper src)
{
_jsonFactory = src._jsonFactory.copy();
_jsonFactory.setCodec(this);
_subtypeResolver = src._subtypeResolver;
_rootNames = new RootNameLookup();
_typeFactory = src._typeFactory;
_injectableValues = src._injectableValues;
HashMap<ClassKey,Class<?>> mixins = new HashMap<ClassKey,Class<?>>(src._mixInAnnotations);
_mixInAnnotations = mixins;
_serializationConfig = new SerializationConfig(src._serializationConfig, mixins);
_deserializationConfig = new DeserializationConfig(src._deserializationConfig, mixins);
_serializerProvider = src._serializerProvider.copy();
_deserializationContext = src._deserializationContext.copy();
// Default serializer factory is stateless, can just assign
_serializerFactory = src._serializerFactory;
}
/**
* Constructs instance that uses specified {@link JsonFactory}
* for constructing necessary {@link JsonParser}s and/or
* {@link JsonGenerator}s, and uses given providers for accessing
* serializers and deserializers.
*
* @param jf JsonFactory to use: if null, a new {@link MappingJsonFactory} will be constructed
* @param sp SerializerProvider to use: if null, a {@link SerializerProvider} will be constructed
* @param dc Blueprint deserialization context instance to use for creating
* actual
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> context objects; if null, will construct standard
* {@link DeserializationContext}
*/
public ObjectMapper(JsonFactory jf,
DefaultSerializerProvider sp, DefaultDeserializationContext dc)
{
/* 02-Mar-2009, tatu: Important: we MUST default to using
* the mapping factory, otherwise tree serialization will
* have problems with POJONodes.
* 03-Jan-2010, tatu: and obviously we also must pass 'this',
* to create actual linking.
*/
if (jf == null) {
_jsonFactory = new MappingJsonFactory(this);
} else {
_jsonFactory = jf;
if (jf.getCodec() == null) { // as per [JACKSON-741]
_jsonFactory.setCodec(this);
}
}
_subtypeResolver = new StdSubtypeResolver();
_rootNames = new RootNameLookup();
// and default type factory is shared one
_typeFactory = TypeFactory.defaultInstance();
HashMap<ClassKey,Class<?>> mixins = new HashMap<ClassKey,Class<?>>();
_mixInAnnotations = mixins;
BaseSettings base = DEFAULT_BASE.withClassIntrospector(defaultClassIntrospector());
_serializationConfig = new SerializationConfig(base,
_subtypeResolver, mixins);
_deserializationConfig = new DeserializationConfig(base,
_subtypeResolver, mixins);
// Some overrides we may need
final boolean needOrder = _jsonFactory.requiresPropertyOrdering();
if (needOrder ^ _serializationConfig.isEnabled(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)) {
configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, needOrder);
}
_serializerProvider = (sp == null) ? new DefaultSerializerProvider.Impl() : sp;
_deserializationContext = (dc == null) ?
new DefaultDeserializationContext.Impl(BeanDeserializerFactory.instance) : dc;
// Default serializer factory is stateless, can just assign
_serializerFactory = BeanSerializerFactory.instance;
}
/**
* Overridable helper method used to construct default {@link ClassIntrospector}
* to use.
*
* @since 2.5
*/
protected ClassIntrospector defaultClassIntrospector() {
return new BasicClassIntrospector();
}
/*
/**********************************************************
/* Methods sub-classes MUST override
/**********************************************************
*/
/**
* Method for creating a new {@link ObjectMapper} instance that
* has same initial configuration as this instance. Note that this
* also requires making a copy of the underlying {@link JsonFactory}
* instance.
*<p>
* Method is typically
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> * used when multiple, differently configured mappers are needed.
* Although configuration is shared, cached serializers and deserializers
* are NOT shared, which means that the new instance may be re-configured
* before use; meaning that it behaves the same way as if an instance
* was constructed from scratch.
*
* @since 2.1
*/
public ObjectMapper copy() {
_checkInvalidCopy(ObjectMapper.class);
return new ObjectMapper(this);
}
/**
* @since 2.1
*/
protected void _checkInvalidCopy(Class<?> exp)
{
if (getClass() != exp) {
throw new IllegalStateException("Failed copy(): "+getClass().getName()
+" (version: "+version()+") does not override copy(); it has to");
}
}
/*
/**********************************************************
/* Methods sub-classes MUST override if providing custom
/* ObjectReader/ObjectWriter implementations
/**********************************************************
*/
/**
* Factory method sub-classes must override, to produce {@link ObjectReader}
* instances of proper sub-type
*
* @since 2.5
*/
protected ObjectReader _newReader(DeserializationConfig config) {
return new ObjectReader(this, config);
}
/**
* Factory method sub-classes must override, to produce {@link ObjectReader}
* instances of proper sub-type
*
* @since 2.5
*/
protected ObjectReader _newReader(DeserializationConfig config,
JavaType valueType, Object valueToUpdate,
FormatSchema schema, InjectableValues injectableValues) {
return new ObjectReader(this, config, valueType, valueToUpdate, schema, injectableValues);
}
/**
* Factory method sub-classes must override, to produce {@link ObjectWriter}
* instances of proper sub-type
*
* @since 2.5
*/
protected ObjectWriter _newWriter(SerializationConfig config) {
return new ObjectWriter(this, config);
}
/**
* Factory method sub-classes must override, to produce {@link ObjectWriter}
* instances of proper sub-type
*
* @since 2.5
*/
protected ObjectWriter _newWriter(SerializationConfig config, FormatSchema schema) {
return new ObjectWriter(this, config, schema);
}
/**
* Factory method sub-classes must override, to produce {@link ObjectWriter}
* instances of proper sub-type
*
* @since 2.5
*/
protected ObjectWriter _newWriter(SerializationConfig config,
JavaType rootType, PrettyPrinter pp) {
return new ObjectWriter(this, config, rootType, pp);
}
/*
/**********************************************************
/* Versioned impl
/**********************************************************
*/
/**
* Method that will return
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>(ai);
mapper._serializationConfig = mapper._serializationConfig.withAppendedAnnotationIntrospector(ai);
}
@Override
public void registerSubtypes(Class<?>... subtypes) {
mapper.registerSubtypes(subtypes);
}
@Override
public void registerSubtypes(NamedType... subtypes) {
mapper.registerSubtypes(subtypes);
}
@Override
public void setMixInAnnotations(Class<?> target, Class<?> mixinSource) {
mapper.addMixIn(target, mixinSource);
}
@Override
public void addDeserializationProblemHandler(DeserializationProblemHandler handler) {
mapper.addHandler(handler);
}
@Override
public void setNamingStrategy(PropertyNamingStrategy naming) {
mapper.setPropertyNamingStrategy(naming);
}
});
return this;
}
/**
* Convenience method for registering specified modules in order;
* functionally equivalent to:
*<pre>
* for (Module module : modules) {
* registerModule(module);
* }
*</pre>
*
* @since 2.2
*/
public ObjectMapper registerModules(Module... modules)
{
for (Module module : modules) {
registerModule(module);
}
return this;
}
/**
* Convenience method for registering specified modules in order;
* functionally equivalent to:
*<pre>
* for (Module module : modules) {
* registerModule(module);
* }
*</pre>
*
* @since 2.2
*/
public ObjectMapper registerModules(Iterable<Module> modules)
{
for (Module module : modules) {
registerModule(module);
}
return this;
}
/**
* Method for locating available methods, using JDK {@link ServiceLoader}
* facility, along with module-provided SPI.
*<p>
* Note that method does not do any caching, so calls should be considered
* potentially expensive.
*
* @since 2.2
*/
public static List<Module> findModules() {
return findModules(null);
}
/**
* Method for locating available methods, using JDK {@link ServiceLoader}
* facility, along with module-provided SPI.
*<p>
* Note that method does not do any caching, so calls should be considered
* potentially expensive.
*
* @since 2.2
*/
public static List<Module> findModules(ClassLoader classLoader)
{
ArrayList<Module> modules = new ArrayList<Module>();
ServiceLoader<Module> loader = (classLoader == null) ?
ServiceLoader.load(Module.class) : ServiceLoader.load(Module.class, classLoader);
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Provider p) {
_serializerProvider = p;
return this;
}
public SerializerProvider getSerializerProvider() {
return _serializerProvider;
}
/*
/**********************************************************
/* Configuration: mix-in annotations
/**********************************************************
*/
/**
* Method to use for defining mix-in annotations to use for augmenting
* annotations that processable (serializable / deserializable)
* classes have.
* Mixing in is done when introspecting class annotations and properties.
* Map passed contains keys that are target classes (ones to augment
* with new annotation overrides), and values that are source classes
* (have annotations to use for augmentation).
* Annotations from source classes (and their supertypes)
* will <b>override</b>
* annotations that target classes (and their super-types) have.
*
* @since 2.5
*/
public ObjectMapper setMixIns(Map<Class<?>, Class<?>> sourceMixins)
{
_mixInAnnotations.clear();
if (sourceMixins != null && sourceMixins.size() > 0) {
for (Map.Entry<Class<?>,Class<?>> en : sourceMixins.entrySet()) {
_mixInAnnotations.put(new ClassKey(en.getKey()), en.getValue());
}
}
return this;
}
/**
* Method to use for adding mix-in annotations to use for augmenting
* specified class or interface. All annotations from
* <code>mixinSource</code> are taken to override annotations
* that <code>target</code> (or its supertypes) has.
*
* @param target Class (or interface) whose annotations to effectively override
* @param mixinSource Class (or interface) whose annotations are to
* be "added" to target's annotations, overriding as necessary
*
* @since 2.5
*/
public ObjectMapper addMixIn(Class<?> target, Class<?> mixinSource)
{
_mixInAnnotations.put(new ClassKey(target), mixinSource);
return this;
}
public Class<?> findMixInClassFor(Class<?> cls) {
return (_mixInAnnotations == null) ? null : _mixInAnnotations.get(new ClassKey(cls));
}
public int mixInCount() {
return (_mixInAnnotations == null) ? 0 : _mixInAnnotations.size();
}
/**
* @deprecated Since 2.5: replaced by a fluent form of the method; {@link #setMixIns}.
*/
@Deprecated
public void setMixInAnnotations(Map<Class<?>, Class<?>> sourceMixins) {
setMixIns(sourceMixins);
}
/**
* @deprecated Since
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>2.5: replaced by a fluent form of the method; {@link #addMixIn(Class, Class)}.
*/
@Deprecated
public final void addMixInAnnotations(Class<?> target, Class<?> mixinSource) {
addMixIn(target, mixinSource);
}
/*
/**********************************************************
/* Configuration, introspection
/**********************************************************
*/
/**
* Method for accessing currently configured visibility checker;
* object used for determining whether given property element
* (method, field, constructor) can be auto-detected or not.
*/
public VisibilityChecker<?> getVisibilityChecker() {
return _serializationConfig.getDefaultVisibilityChecker();
}
/**
* Method for setting currently configured visibility checker;
* object used for determining whether given property element
* (method, field, constructor) can be auto-detected or not.
* This default checker is used if no per-class overrides
* are defined.
*/
public void setVisibilityChecker(VisibilityChecker<?> vc) {
_deserializationConfig = _deserializationConfig.with(vc);
_serializationConfig = _serializationConfig.with(vc);
}
/**
* Convenience method that allows changing configuration for
* underlying {@link VisibilityChecker}s, to change details of what kinds of
* properties are auto-detected.
* Basically short cut for doing:
*<pre>
* mapper.setVisibilityChecker(
* mapper.getVisibilityChecker().withVisibility(forMethod, visibility)
* );
*</pre>
* one common use case would be to do:
*<pre>
* mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY);
*</pre>
* which would make all member fields serializable without further annotations,
* instead of just public fields (default setting).
*
* @param forMethod Type of property descriptor affected (field, getter/isGetter,
* setter, creator)
* @param visibility Minimum visibility to require for the property descriptors of type
*
* @return Modified mapper instance (that is, "this"), to allow chaining
* of configuration calls
*/
public ObjectMapper setVisibility(PropertyAccessor forMethod, JsonAutoDetect.Visibility visibility)
{
_deserializationConfig = _deserializationConfig.withVisibility(forMethod, visibility);
_serializationConfig = _serializationConfig.withVisibility(forMethod, visibility);
return this;
}
/**
* Method for accessing subtype resolver in use.
*/
public SubtypeResolver getSubtypeResolver() {
return _subtypeResolver;
}
/**
* Method for setting custom subtype resolver to use.
*/
public ObjectMapper setSubtypeResolver(SubtypeResolver str) {
_subtypeResolver = str;
_deserializationConfig = _deserializationConfig.with(str);
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> as details of how information is embedded.
*
* @param typer Type information inclusion handler
*/
public ObjectMapper setDefaultTyping(TypeResolverBuilder<?> typer) {
_deserializationConfig = _deserializationConfig.with(typer);
_serializationConfig = _serializationConfig.with(typer);
return this;
}
/**
* Method for registering specified class as a subtype, so that
* typename-based resolution can link supertypes to subtypes
* (as an alternative to using annotations).
* Type for given class is determined from appropriate annotation;
* or if missing, default name (unqualified class name)
*/
public void registerSubtypes(Class<?>... classes) {
getSubtypeResolver().registerSubtypes(classes);
}
/**
* Method for registering specified class as a subtype, so that
* typename-based resolution can link supertypes to subtypes
* (as an alternative to using annotations).
* Name may be provided as part of argument, but if not will
* be based on annotations or use default name (unqualified
* class name).
*/
public void registerSubtypes(NamedType... types) {
getSubtypeResolver().registerSubtypes(types);
}
/*
/**********************************************************
/* Configuration, basic type handling
/**********************************************************
*/
/**
* Accessor for getting currently configured {@link TypeFactory} instance.
*/
public TypeFactory getTypeFactory() {
return _typeFactory;
}
/**
* Method that can be used to override {@link TypeFactory} instance
* used by this mapper.
*<p>
* Note: will also set {@link TypeFactory} that deserialization and
* serialization config objects use.
*/
public ObjectMapper setTypeFactory(TypeFactory f)
{
_typeFactory = f;
_deserializationConfig = _deserializationConfig.with(f);
_serializationConfig = _serializationConfig.with(f);
return this;
}
/**
* Convenience method for constructing {@link JavaType} out of given
* type (typically <code>java.lang.Class</code>), but without explicit
* context.
*/
public JavaType constructType(Type t) {
return _typeFactory.constructType(t);
}
/*
/**********************************************************
/* Configuration, deserialization
/**********************************************************
*/
/**
* Method that can be used to get hold of {@link JsonNodeFactory}
* that this mapper will use when directly constructing
* root {@link JsonNode} instances for Trees.
*<p>
* Note: this is just a shortcut for calling
*<pre>
* getDeserializationConfig().getNodeFactory()
*</pre>
*/
public JsonNodeFactory getNodeFactory() {
return _deserialization
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> can not be introspected when using this method.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@Override
@SuppressWarnings("unchecked")
public <T> T readValue(JsonParser jp, Class<T> valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readValue(getDeserializationConfig(), jp, _typeFactory.constructType(valueType));
}
/**
* Method to deserialize JSON content into a Java type, reference
* to which is passed as argument. Type is passed using so-called
* "super type token" (see )
* and specifically needs to be used if the root type is a
* parameterized (generic) container type.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@Override
@SuppressWarnings("unchecked")
public <T> T readValue(JsonParser jp, TypeReference<?> valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readValue(getDeserializationConfig(), jp, _typeFactory.constructType(valueTypeRef));
}
/**
* Method to deserialize JSON content into a Java type, reference
* to which is passed as argument. Type is passed using
* Jackson specific type; instance of which can be constructed using
* {@link TypeFactory}.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>> MappingIterator<T> readValues(JsonParser jp, Class<T> valueType)
throws IOException, JsonProcessingException
{
return readValues(jp, _typeFactory.constructType(valueType));
}
/**
* Method for reading sequence of Objects from parser stream.
*/
@Override
public <T> MappingIterator<T> readValues(JsonParser jp, TypeReference<?> valueTypeRef)
throws IOException, JsonProcessingException
{
return readValues(jp, _typeFactory.constructType(valueTypeRef));
}
/*
/**********************************************************
/* Public API not included in ObjectCodec: deserialization
/* (mapping from JSON to Java types)
/**********************************************************
*/
/**
* Method to deserialize JSON content as tree expressed
* using set of {@link JsonNode} instances.
* Returns root of the resulting tree (where root can consist
* of just a single node if the current event is a
* value event, not container).
*<p>
* If a low-level I/O problem (missing input, network error) occurs,
* a {@link IOException} will be thrown.
* If a parsing problem occurs (invalid JSON),
* {@link JsonParseException} will be thrown.
* If no content is found from input (end-of-input), Java
* <code>null</code> will be returned.
*
* @param in Input stream used to read JSON content
* for building the JSON tree.
*
* @return a {@link JsonNode}, if valid JSON content found; null
* if input has no content to bind -- note, however, that if
* JSON <code>null</code> token is found, it will be represented
* as a non-null {@link JsonNode} (one that returns <code>true</code>
* for {@link JsonNode#isNull()}
*
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
*/
public JsonNode readTree(InputStream in)
throws IOException, JsonProcessingException
{
JsonNode n = (JsonNode) _readMapAndClose(_jsonFactory.createParser(in), JSON_NODE_TYPE);
return (n == null) ? NullNode.instance : n;
}
/**
* Method to deserialize JSON content as tree expressed
* using set of {@link JsonNode} instances.
* Returns root of the resulting tree (where root can consist
* of just a single node if the current event is a
* value event, not container).
*<p>
* If a low-level I/O problem (missing input, network error) occurs,
* a {@link IOException} will be thrown.
* If a parsing
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>_AFTER_WRITE_VALUE)) {
jgen.flush();
}
}
/**
* Method to serialize given JSON Tree, using generator
* provided.
*/
public void writeTree(JsonGenerator jgen, JsonNode rootNode)
throws IOException, JsonProcessingException
{
SerializationConfig config = getSerializationConfig();
_serializerProvider(config).serializeValue(jgen, rootNode);
if (config.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) {
jgen.flush();
}
}
/**
*<p>
* Note: return type is co-variant, as basic ObjectCodec
* abstraction can not refer to concrete node types (as it's
* part of core package, whereas impls are part of mapper
* package)
*/
@Override
public ObjectNode createObjectNode() {
return _deserializationConfig.getNodeFactory().objectNode();
}
/**
*<p>
* Note: return type is co-variant, as basic ObjectCodec
* abstraction can not refer to concrete node types (as it's
* part of core package, whereas impls are part of mapper
* package)
*/
@Override
public ArrayNode createArrayNode() {
return _deserializationConfig.getNodeFactory().arrayNode();
}
/**
* Method for constructing a {@link JsonParser} out of JSON tree
* representation.
*
* @param n Root node of the tree that resulting parser will read from
*/
@Override
public JsonParser treeAsTokens(TreeNode n) {
return new TreeTraversingParser((JsonNode) n, this);
}
/**
* Convenience conversion method that will bind data given JSON tree
* contains into specific value (usually bean) type.
*<p>
* Functionally equivalent to:
*<pre>
* objectMapper.convertValue(n, valueClass);
*</pre>
*/
@SuppressWarnings("unchecked")
@Override
public <T> T treeToValue(TreeNode n, Class<T> valueType)
throws JsonProcessingException
{
try {
// [Issue-11]: Simple cast when we just want to cast to, say, ObjectNode
// ... one caveat; while everything is Object.class, let's not take shortcut
if (valueType != Object.class && valueType.isAssignableFrom(n.getClass())) {
return (T) n;
}
return readValue(treeAsTokens(n), valueType);
} catch (JsonProcessingException e) {
throw e;
} catch (IOException e) { // should not occur, no real i/o...
throw new IllegalArgumentException(e.getMessage(), e);
}
}
/**
* Reverse of {@link #treeToValue}; given a
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> value (usually bean), will
* construct equivalent JSON Tree representation. Functionally similar
* to serializing value into JSON and parsing JSON as tree, but
* more efficient.
*<p>
* NOTE: one known difference from actual serialization is that so-called
* "raw values" are not supported -- since they are opaque sequence of
* bytes to include (which may or may not be supported by the backend)
* they can not be converted using this method. It may be possible to
* support conversions using full serialization, if raw values must be
* preserved.
*
* @param <T> Actual node type; usually either basic {@link JsonNode} or
* {@link com.fasterxml.jackson.databind.node.ObjectNode}
* @param fromValue Bean value to convert
* @return Root node of the resulting JSON tree
*/
@SuppressWarnings({ "unchecked", "resource" })
public <T extends JsonNode> T valueToTree(Object fromValue)
throws IllegalArgumentException
{
if (fromValue == null) return null;
TokenBuffer buf = new TokenBuffer(this, false);
JsonNode result;
try {
writeValue(buf, fromValue);
JsonParser jp = buf.asParser();
result = readTree(jp);
jp.close();
} catch (IOException e) { // should not occur, no real i/o...
throw new IllegalArgumentException(e.getMessage(), e);
}
return (T) result;
}
/*
/**********************************************************
/* Extended Public API, accessors
/**********************************************************
*/
/**
* Method that can be called to check whether mapper thinks
* it could serialize an instance of given Class.
* Check is done
* by checking whether a serializer can be found for the type.
*<p>
* NOTE: since this method does NOT throw exceptions, but internal
* processing may, caller usually has little information as to why
* serialization would fail. If you want access to internal {@link Exception},
* call {@link #canSerialize(Class, AtomicReference)} instead.
*
* @return True if mapper can find a serializer for instances of
* given class (potentially serializable), false otherwise (not
* serializable)
*/
public boolean canSerialize(Class<?> type) {
return _serializerProvider(getSerializationConfig()).hasSerializerFor(type, null);
}
/**
* Method similar to {@link #canSerialize(Class)} but that can return
* actual {@link Throwable} that was thrown when trying to construct
* serializer: this may be useful in figuring out what the actual problem is.
*
* @since 2.3
*/
public boolean canSerialize(Class<?> type, AtomicReference<Throwable> cause) {
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> return _serializerProvider(getSerializationConfig()).hasSerializerFor(type, cause);
}
/**
* Method that can be called to check whether mapper thinks
* it could deserialize an Object of given type.
* Check is done by checking whether a registered deserializer can
* be found or built for the type; if not (either by no mapping being
* found, or through an <code>Exception</code> being thrown, false
* is returned.
*<p>
* <b>NOTE</b>: in case an exception is thrown during course of trying
* co construct matching deserializer, it will be effectively swallowed.
* If you want access to that exception, call
* {@link #canDeserialize(JavaType, AtomicReference)} instead.
*
* @return True if mapper can find a serializer for instances of
* given class (potentially serializable), false otherwise (not
* serializable)
*/
public boolean canDeserialize(JavaType type)
{
return createDeserializationContext(null,
getDeserializationConfig()).hasValueDeserializerFor(type, null);
}
/**
* Method similar to {@link #canDeserialize(JavaType)} but that can return
* actual {@link Throwable} that was thrown when trying to construct
* serializer: this may be useful in figuring out what the actual problem is.
*
* @since 2.3
*/
public boolean canDeserialize(JavaType type, AtomicReference<Throwable> cause)
{
return createDeserializationContext(null,
getDeserializationConfig()).hasValueDeserializerFor(type, cause);
}
/*
/**********************************************************
/* Extended Public API, deserialization,
/* convenience methods
/**********************************************************
*/
/**
* Method to deserialize JSON content from given file into given Java type.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@SuppressWarnings("unchecked")
public <T> T readValue(File src, Class<T> valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType));
}
/**
* Method to deserialize JSON content from
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>, Class<T> valueType)
throws IOException, JsonParseException, JsonMappingException
{
// !!! TODO
// _setupClassLoaderForDeserialization(valueType);
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType));
}
/**
* Method to deserialize JSON content from given resource into given Java type.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public <T> T readValue(URL src, TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef));
}
@SuppressWarnings("unchecked")
public <T> T readValue(URL src, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType);
}
/**
* Method to deserialize JSON content from given JSON content String.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@SuppressWarnings("unchecked")
public <T> T readValue(String content, Class<T> valueType)
throws IOException, JsonParseException, JsonMappingException
{
// !!! TODO
// _setupClassLoaderForDeserialization(valueType);
return (T) _readMapAndClose(_jsonFactory.createParser(content), _typeFactory.constructType(valueType));
}
/**
* Method to deserialize JSON content from given JSON content String
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public <T> T readValue(String content, TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(content), _typeFactory.constructType(valueTypeRef));
}
/**
* Method to deserialize JSON content from given JSON content String.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@SuppressWarnings("unchecked")
public <T> T readValue(String content, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(content), valueType);
}
@SuppressWarnings("unchecked")
public <T> T readValue(Reader src, Class<T> valueType)
throws IOException, JsonParseException, JsonMappingException
{
// !!! TODO
// _setupClassLoaderForDeserialization(valueType);
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public <T> T readValue(Reader src, TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef));
}
@SuppressWarnings("unchecked")
public <T> T readValue(Reader src, JavaType valueType)
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType);
}
@SuppressWarnings("unchecked")
public <T> T readValue(InputStream src, Class<T> valueType)
throws IOException, JsonParseException, JsonMappingException
{
// !!! TODO
// _setupClassLoaderForDeserialization(valueType);
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public <T> T readValue(InputStream src, TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef));
}
@SuppressWarnings("unchecked")
public <T> T readValue(InputStream src, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType);
}
@SuppressWarnings("unchecked")
public <T> T readValue(byte[] src, Class<T> valueType)
throws IOException, JsonParseException, JsonMappingException
{
// !!! TODO
// _setupClassLoaderForDeserialization(valueType);
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType));
}
@SuppressWarnings("unchecked")
public <T> T readValue(byte[] src, int offset, int len,
Class<T> valueType)
throws IOException, JsonParseException, JsonMappingException
{
// !!! TODO
// _setupClassLoaderForDeserialization(valueType);
return (T) _readMapAndClose(_jsonFactory.createParser(src, offset, len), _typeFactory.constructType(valueType));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public <T> T readValue(byte[] src, TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public <T> T readValue(byte[] src, int offset, int len,
TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src, offset, len), _typeFactory.constructType(valueTypeRef));
}
@SuppressWarnings("unchecked")
public <T> T
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>("unchecked")
public <W extends ObjectWriter> W writer(SerializationFeature first,
SerializationFeature... other) {
return (W) _newWriter(getSerializationConfig().with(first, other));
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified {@link DateFormat}; or, if
* null passed, using timestamp (64-bit number.
*/
@SuppressWarnings("unchecked")
public <W extends ObjectWriter> W writer(DateFormat df) {
return (W) _newWriter(getSerializationConfig().with(df));
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified JSON View (filter).
*/
@SuppressWarnings("unchecked")
public <W extends ObjectWriter> W writerWithView(Class<?> serializationView) {
return (W) _newWriter(getSerializationConfig().withView(serializationView));
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified root type, instead of actual
* runtime type of value. Type must be a super-type of runtime type.
*<p>
* Main reason for using this method is performance, as writer is able
* to pre-fetch serializer to use before write, and if writer is used
* more than once this avoids addition per-value serializer lookups.
*
* @since 2.5
*/
@SuppressWarnings("unchecked")
public <W extends ObjectWriter> W writerFor(Class<?> rootType) {
return (W) _newWriter(getSerializationConfig(),
((rootType == null) ? null :_typeFactory.constructType(rootType)),
/*PrettyPrinter*/null);
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified root type, instead of actual
* runtime type of value. Type must be a super-type of runtime type.
*<p>
* Main reason for using this method is performance, as writer is able
* to pre-fetch serializer to use before write, and if writer is used
* more than once this avoids addition per-value serializer lookups.
*
* @since 2.5
*/
@SuppressWarnings("unchecked")
public <W extends ObjectWriter> W writerFor(TypeReference<?> rootType) {
return (W) _newWriter(getSerializationConfig(),
((rootType == null) ? null : _typeFactory.constructType(rootType)),
/*PrettyPrinter*/null);
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified root type, instead of actual
* runtime type of value. Type must be a super-type of runtime type.
*<
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>p>
* Main reason for using this method is performance, as writer is able
* to pre-fetch serializer to use before write, and if writer is used
* more than once this avoids addition per-value serializer lookups.
*
* @since 2.5
*/
@SuppressWarnings("unchecked")
public <W extends ObjectWriter> W writerFor(JavaType rootType) {
return (W) _newWriter(getSerializationConfig(), rootType, /*PrettyPrinter*/null);
}
/**
* @deprecated Since 2.5, use {@link #writerFor(Class)} instead
*/
@SuppressWarnings("unchecked")
@Deprecated
public <W extends ObjectWriter> W writerWithType(Class<?> rootType) {
return (W) _newWriter(getSerializationConfig(),
// 15-Mar-2013, tatu: Important! Indicate that static typing is needed:
((rootType == null) ? null :_typeFactory.constructType(rootType)),
/*PrettyPrinter*/null);
}
/**
* @deprecated Since 2.5, use {@link #writerFor(TypeReference)} instead
*/
@SuppressWarnings("unchecked")
@Deprecated
public <W extends ObjectWriter> W writerWithType(TypeReference<?> rootType) {
return (W) _newWriter(getSerializationConfig(),
// 15-Mar-2013, tatu: Important! Indicate that static typing is needed:
((rootType == null) ? null : _typeFactory.constructType(rootType)),
/*PrettyPrinter*/null);
}
/**
* @deprecated Since 2.5, use {@link #writerFor(JavaType)} instead
*/
@SuppressWarnings("unchecked")
@Deprecated
public <W extends ObjectWriter> W writerWithType(JavaType rootType) {
return (W) _newWriter(getSerializationConfig(), rootType, /*PrettyPrinter*/null);
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified pretty printer for indentation
* (or if null, no pretty printer)
*/
@SuppressWarnings("unchecked")
public <W extends ObjectWriter> W writer(PrettyPrinter pp) {
if (pp == null) { // need to use a marker to indicate explicit disabling of pp
pp = ObjectWriter.NULL_PRETTY_PRINTER;
}
return (W) _newWriter(getSerializationConfig(), /*root type*/ null, pp);
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using the default pretty printer for indentation
*/
@SuppressWarnings("unchecked")
public <W extends ObjectWriter> W writerWithDefaultPrettyPrinter() {
return (W) _newWriter(getSerializationConfig(),
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>T extends ObjectReader> T reader(DeserializationFeature feature) {
return (T) _newReader(getDeserializationConfig().with(feature));
}
/**
* Factory method for constructing {@link ObjectReader} with
* specified features enabled (compared to settings that this
* mapper instance has).
* Note that the resulting instance is NOT usable as is,
* without defining expected value type.
*/
@SuppressWarnings("unchecked")
public <T extends ObjectReader> T reader(DeserializationFeature first,
DeserializationFeature... other) {
return (T) _newReader(getDeserializationConfig().with(first, other));
}
/**
* Factory method for constructing {@link ObjectReader} that will
* update given Object (usually Bean, but can be a Collection or Map
* as well, but NOT an array) with JSON data. Deserialization occurs
* normally except that the root-level value in JSON is not used for
* instantiating a new object; instead give updateable object is used
* as root.
* Runtime type of value object is used for locating deserializer,
* unless overridden by other factory methods of {@link ObjectReader}
*/
@SuppressWarnings("unchecked")
public <T extends ObjectReader> T readerForUpdating(Object valueToUpdate) {
JavaType t = _typeFactory.constructType(valueToUpdate.getClass());
return (T) _newReader(getDeserializationConfig(), t, valueToUpdate,
null, _injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* read or update instances of specified type
*/
@SuppressWarnings("unchecked")
public <T extends ObjectReader> T reader(JavaType type) {
return (T) _newReader(getDeserializationConfig(), type, null,
null, _injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* read or update instances of specified type
*/
@SuppressWarnings("unchecked")
public <T extends ObjectReader> T reader(Class<?> type) {
return (T) _newReader(getDeserializationConfig(), _typeFactory.constructType(type), null,
null, _injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* read or update instances of specified type
*/
@SuppressWarnings("unchecked")
public <T extends ObjectReader> T reader(TypeReference<?> type) {
return (T)_newReader(getDeserializationConfig(), _typeFactory.constructType(type), null,
null, _injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* use specified {@link JsonNodeFactory} for constructing JSON trees.
*/
@SuppressWarnings("unchecked")
public <T
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> extends ObjectReader> T reader(JsonNodeFactory f) {
return (T) _newReader(getDeserializationConfig()).with(f);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* pass specific schema object to {@link JsonParser} used for
* reading content.
*
* @param schema Schema to pass to parser
*/
@SuppressWarnings("unchecked")
public <T extends ObjectReader> T reader(FormatSchema schema) {
_verifySchemaType(schema);
return (T)_newReader(getDeserializationConfig(), null, null,
schema, _injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* use specified injectable values.
*
* @param injectableValues Injectable values to use
*/
@SuppressWarnings("unchecked")
public <T extends ObjectReader> T reader(InjectableValues injectableValues) {
return (T)_newReader(getDeserializationConfig(), null, null,
null, injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* deserialize objects using specified JSON View (filter).
*/
@SuppressWarnings("unchecked")
public <T extends ObjectReader> T readerWithView(Class<?> view) {
return (T) _newReader(getDeserializationConfig().withView(view));
}
/**
* Factory method for constructing {@link ObjectReader} that will
* use specified Base64 encoding variant for Base64-encoded binary data.
*
* @since 2.1
*/
@SuppressWarnings("unchecked")
public <T extends ObjectReader> T reader(Base64Variant defaultBase64) {
return (T) _newReader(getDeserializationConfig().with(defaultBase64));
}
/**
* Factory method for constructing {@link ObjectReader} that will
* use specified default attributes.
*
* @since 2.3
*/
@SuppressWarnings("unchecked")
public <T extends ObjectReader> T reader(ContextAttributes attrs) {
return (T) _newReader(getDeserializationConfig().with(attrs));
}
/*
/**********************************************************
/* Extended Public API: convenience type conversion
/**********************************************************
*/
/**
* Convenience method for doing two-step conversion from given value, into
* instance of given value type. This is functionality equivalent to first
* serializing given value into JSON, then binding JSON data into value
* of given type, but may be executed without fully serializing into
* JSON. Same converters (serializers, deserializers) will be used as for
* data binding, meaning same object mapper configuration works.
*
* @throws IllegalArgumentException If conversion fails due to incompatible type;
* if so, root cause will contain
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> underlying checked exception data binding
* functionality threw
*/
@SuppressWarnings("unchecked")
public <T> T convertValue(Object fromValue, Class<T> toValueType)
throws IllegalArgumentException
{
// sanity check for null first:
if (fromValue == null) return null;
return (T) _convert(fromValue, _typeFactory.constructType(toValueType));
}
@SuppressWarnings("unchecked")
public <T> T convertValue(Object fromValue, TypeReference<?> toValueTypeRef)
throws IllegalArgumentException
{
return (T) convertValue(fromValue, _typeFactory.constructType(toValueTypeRef));
}
@SuppressWarnings("unchecked")
public <T> T convertValue(Object fromValue, JavaType toValueType)
throws IllegalArgumentException
{
// sanity check for null first:
if (fromValue == null) return null;
return (T) _convert(fromValue, toValueType);
}
/**
* Actual conversion implementation: instead of using existing read
* and write methods, much of code is inlined. Reason for this is
* that we must avoid root value wrapping/unwrapping both for efficiency and
* for correctness. If root value wrapping/unwrapping is actually desired,
* caller must use explicit <code>writeValue</code> and
* <code>readValue</code> methods.
*/
@SuppressWarnings("resource")
protected Object _convert(Object fromValue, JavaType toValueType)
throws IllegalArgumentException
{
// also, as per [Issue-11], consider case for simple cast
/* But with caveats: one is that while everything is Object.class, we don't
* want to "optimize" that out; and the other is that we also do not want
* to lose conversions of generic types.
*/
Class<?> targetType = toValueType.getRawClass();
if (targetType != Object.class
&& !toValueType.hasGenericTypes()
&& targetType.isAssignableFrom(fromValue.getClass())) {
return fromValue;
}
/* Then use TokenBuffer, which is a JsonGenerator:
* (see [JACKSON-175])
*/
TokenBuffer buf = new TokenBuffer(this, false);
try {
// inlined 'writeValue' with minor changes:
// first: disable wrapping when writing
SerializationConfig config = getSerializationConfig().without(SerializationFeature.WRAP_ROOT_VALUE);
// no need to check for closing of TokenBuffer
_serializerProvider(config).serializeValue(buf, fromValue);
// then matching read, inlined 'readValue' with minor mods:
final JsonParser jp = buf.asParser();
Object result;
// ok to pass in existing feature flags; unwrapping handled by mapper
final DeserializationConfig deserConfig =
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> getDeserializationConfig();
JsonToken t = _initForReading(jp);
if (t == JsonToken.VALUE_NULL) {
DeserializationContext ctxt = createDeserializationContext(jp, deserConfig);
result = _findRootDeserializer(ctxt, toValueType).getNullValue();
} else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) {
result = null;
} else { // pointing to event other than null
DeserializationContext ctxt = createDeserializationContext(jp, deserConfig);
JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, toValueType);
// note: no handling of unwarpping
result = deser.deserialize(jp, ctxt);
}
jp.close();
return result;
} catch (IOException e) { // should not occur, no real i/o...
throw new IllegalArgumentException(e.getMessage(), e);
}
}
/*
/**********************************************************
/* Extended Public API: JSON Schema generation
/**********************************************************
*/
/**
* Generate <a href="http://json-schema.org/">Json-schema</a>
* instance for specified class.
*
* @param t The class to generate schema for
* @return Constructed JSON schema.
*/
@SuppressWarnings("deprecation")
public com.fasterxml.jackson.databind.jsonschema.JsonSchema generateJsonSchema(Class<?> t)
throws JsonMappingException {
return _serializerProvider(getSerializationConfig()).generateJsonSchema(t);
}
/**
* Method for visiting type hierarchy for given type, using specified visitor.
*<p>
* This method can be used for things like
* generating <a href="http://json-schema.org/">Json Schema</a>
* instance for specified type.
*
* @param type Type to generate schema for (possibly with generic signature)
*
* @since 2.1
*/
public void acceptJsonFormatVisitor(Class<?> type, JsonFormatVisitorWrapper visitor)
throws JsonMappingException
{
acceptJsonFormatVisitor(_typeFactory.constructType(type), visitor);
}
/**
* Method for visiting type hierarchy for given type, using specified visitor.
* Visitation uses <code>Serializer</code> hierarchy and related properties
*<p>
* This method can be used for things like
* generating <a href="http://json-schema.org/">Json Schema</a>
* instance for specified type.
*
* @param type Type to generate schema for (possibly with generic signature)
*
* @since 2.1
*/
public void acceptJsonFormatVisitor(JavaType type, JsonFormatVisitorWrapper visitor)
throws JsonMappingException
{
if (type == null) {
throw
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> new IllegalArgumentException("type must be provided");
}
_serializerProvider(getSerializationConfig()).acceptJsonFormatVisitor(type, visitor);
}
/*
/**********************************************************
/* Internal methods for serialization, overridable
/**********************************************************
*/
/**
* Overridable helper method used for constructing
* {@link SerializerProvider} to use for serialization.
*/
protected DefaultSerializerProvider _serializerProvider(SerializationConfig config) {
return _serializerProvider.createInstance(config, _serializerFactory);
}
/**
* Helper method that should return default pretty-printer to
* use for generators constructed by this mapper, when instructed
* to use default pretty printer.
*/
protected PrettyPrinter _defaultPrettyPrinter() {
return _defaultPrettyPrinter;
}
/**
* Method called to configure the generator as necessary and then
* call write functionality
*/
protected final void _configAndWriteValue(JsonGenerator jgen, Object value)
throws IOException
{
SerializationConfig cfg = getSerializationConfig();
cfg.initialize(jgen); // since 2.5
if (cfg.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) {
_configAndWriteCloseable(jgen, value, cfg);
return;
}
boolean closed = false;
try {
_serializerProvider(cfg).serializeValue(jgen, value);
closed = true;
jgen.close();
} finally {
/* won't try to close twice; also, must catch exception (so it
* will not mask exception that is pending)
*/
if (!closed) {
/* 04-Mar-2014, tatu: But! Let's try to prevent auto-closing of
* structures, which typically causes more damage.
*/
jgen.disable(JsonGenerator.Feature.AUTO_CLOSE_JSON_CONTENT);
try {
jgen.close();
} catch (IOException ioe) { }
}
}
}
protected final void _configAndWriteValue(JsonGenerator jgen, Object value, Class<?> viewClass)
throws IOException
{
SerializationConfig cfg = getSerializationConfig().withView(viewClass);
cfg.initialize(jgen); // since 2.5
// [JACKSON-282]: consider Closeable
if (cfg.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) {
_configAndWriteCloseable(jgen, value, cfg);
return;
}
boolean closed = false;
try {
_serializerProvider(cfg).serializeValue(jgen, value);
closed = true;
jgen.close();
} finally {
if (!closed) {
// 04-Mar-2014,
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Type+")");
}
return _findTypeResolver(config, am, containerType);
}
@Override
public List<NamedType> findSubtypes(Annotated a)
{
JsonSubTypes t = _findAnnotation(a, JsonSubTypes.class);
if (t == null) return null;
JsonSubTypes.Type[] types = t.value();
ArrayList<NamedType> result = new ArrayList<NamedType>(types.length);
for (JsonSubTypes.Type type : types) {
result.add(new NamedType(type.value(), type.name()));
}
return result;
}
@Override
public String findTypeName(AnnotatedClass ac)
{
JsonTypeName tn = _findAnnotation(ac, JsonTypeName.class);
return (tn == null) ? null : tn.value();
}
/*
/**********************************************************
/* Serialization: general annotations
/**********************************************************
*/
@Override
public Object findSerializer(Annotated a)
{
JsonSerialize ann = _findAnnotation(a, JsonSerialize.class);
if (ann != null) {
Class<? extends JsonSerializer<?>> serClass = ann.using();
if (serClass != JsonSerializer.None.class) {
return serClass;
}
}
/* 18-Oct-2010, tatu: [JACKSON-351] @JsonRawValue handled just here, for now;
* if we need to get raw indicator from other sources need to add
* separate accessor within {@link AnnotationIntrospector} interface.
*/
JsonRawValue annRaw = _findAnnotation(a, JsonRawValue.class);
if ((annRaw != null) && annRaw.value()) {
// let's construct instance with nominal type:
Class<?> cls = a.getRawType();
return new RawSerializer<Object>(cls);
}
return null;
}
@Override
public Class<? extends JsonSerializer<?>> findKeySerializer(Annotated a)
{
JsonSerialize ann = _findAnnotation(a, JsonSerialize.class);
if (ann != null) {
Class<? extends JsonSerializer<?>> serClass = ann.keyUsing();
if (serClass != JsonSerializer.None.class) {
return serClass;
}
}
return null;
}
@Override
public Class<? extends JsonSerializer<?>> findContentSerializer(Annotated a)
{
JsonSerialize ann = _findAnnotation(a, JsonSerialize.class);
if (ann != null) {
Class<? extends JsonSerializer<?>> serClass = ann.contentUsing();
if (serClass != JsonSerializer.None.class) {
return serClass;
}
}
return null;
}
@Override
public Object findNullSerializer(Annotated a)
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> {
JsonSerialize ann = _findAnnotation(a, JsonSerialize.class);
if (ann != null) {
Class<? extends JsonSerializer<?>> serClass = ann.nullsUsing();
if (serClass != JsonSerializer.None.class) {
return serClass;
}
}
return null;
}
@Override
public JsonInclude.Include findSerializationInclusion(Annotated a, JsonInclude.Include defValue)
{
JsonInclude inc = _findAnnotation(a, JsonInclude.class);
if (inc != null) {
return inc.value();
}
JsonSerialize ann = _findAnnotation(a, JsonSerialize.class);
if (ann != null) {
@SuppressWarnings("deprecation")
JsonSerialize.Inclusion i2 = ann.include();
switch (i2) {
case ALWAYS:
return JsonInclude.Include.ALWAYS;
case NON_NULL:
return JsonInclude.Include.NON_NULL;
case NON_DEFAULT:
return JsonInclude.Include.NON_DEFAULT;
case NON_EMPTY:
return JsonInclude.Include.NON_EMPTY;
case DEFAULT_INCLUSION: // since 2.3 -- fall through, use default
break;
}
}
return defValue;
}
@Override
public JsonInclude.Include findSerializationInclusionForContent(Annotated a, JsonInclude.Include defValue)
{
JsonInclude inc = _findAnnotation(a, JsonInclude.class);
return (inc == null) ? defValue : inc.content();
}
@Override
public Class<?> findSerializationType(Annotated am)
{
JsonSerialize ann = _findAnnotation(am, JsonSerialize.class);
return (ann == null) ? null : _classIfExplicit(ann.as());
}
@Override
public Class<?> findSerializationKeyType(Annotated am, JavaType baseType)
{
JsonSerialize ann = _findAnnotation(am, JsonSerialize.class);
return (ann == null) ? null : _classIfExplicit(ann.keyAs());
}
@Override
public Class<?> findSerializationContentType(Annotated am, JavaType baseType)
{
JsonSerialize ann = _findAnnotation(am, JsonSerialize.class);
return (ann == null) ? null : _classIfExplicit(ann.contentAs());
}
@Override
public JsonSerialize.Typing findSerializationTyping(Annotated a)
{
JsonSerialize ann = _findAnnotation(a, JsonSerialize.class);
return (ann == null) ? null : ann.typing();
}
@Override
public Object findSerializationConverter(Annotated a) {
JsonSerialize ann = _findAnnotation(a, JsonSerialize.class);
return (ann == null) ? null : _classIfExplicit
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>(ann.converter(), Converter.None.class);
}
@Override
public Object findSerializationContentConverter(AnnotatedMember a) {
JsonSerialize ann = _findAnnotation(a, JsonSerialize.class);
return (ann == null) ? null : _classIfExplicit(ann.contentConverter(), Converter.None.class);
}
@Override
public Class<?>[] findViews(Annotated a)
{
JsonView ann = _findAnnotation(a, JsonView.class);
return (ann == null) ? null : ann.value();
}
@Override
public Boolean isTypeId(AnnotatedMember member) {
return _hasAnnotation(member, JsonTypeId.class);
}
@Override
public ObjectIdInfo findObjectIdInfo(Annotated ann) {
JsonIdentityInfo info = _findAnnotation(ann, JsonIdentityInfo.class);
if (info == null || info.generator() == ObjectIdGenerators.None.class) {
return null;
}
// In future may need to allow passing namespace?
PropertyName name = new PropertyName(info.property());
return new ObjectIdInfo(name, info.scope(), info.generator(), info.resolver());
}
@Override
public ObjectIdInfo findObjectReferenceInfo(Annotated ann, ObjectIdInfo objectIdInfo) {
JsonIdentityReference ref = _findAnnotation(ann, JsonIdentityReference.class);
if (ref != null) {
objectIdInfo = objectIdInfo.withAlwaysAsId(ref.alwaysAsId());
}
return objectIdInfo;
}
@Override
public JsonFormat.Value findFormat(Annotated ann) {
JsonFormat f = _findAnnotation(ann, JsonFormat.class);
return (f == null) ? null : new JsonFormat.Value(f);
}
@Override
public String findPropertyDefaultValue(Annotated ann) {
JsonProperty prop = _findAnnotation(ann, JsonProperty.class);
if (prop == null) {
return null;
}
String str = prop.defaultValue();
// Since annotations do not allow nulls, need to assume empty means "none"
return str.isEmpty() ? null : str;
}
@Override
public String findPropertyDescription(Annotated ann) {
JsonPropertyDescription desc = _findAnnotation(ann, JsonPropertyDescription.class);
return (desc == null) ? null : desc.value();
}
@Override
public Integer findPropertyIndex(Annotated ann) {
JsonProperty prop = _findAnnotation(ann, JsonProperty.class);
if (prop != null) {
int ix = prop.index();
if (ix != JsonProperty.INDEX_UNKNOWN) {
return Integer.valueOf(ix);
}
}
return null;
}
@Override
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> if none, default to attribute name
PropertyName propName = _propertyName(attr.propName(), attr.propNamespace());
if (!propName.hasSimpleName()) {
propName = new PropertyName(attrName);
}
// now, then, we need a placeholder for member (no real Field/Method):
AnnotatedMember member = new VirtualAnnotatedMember(ac, ac.getRawType(),
attrName, type.getRawClass());
// and with that and property definition
SimpleBeanPropertyDefinition propDef = SimpleBeanPropertyDefinition.construct(config,
member, propName, metadata, attr.include());
// can construct the property writer
return AttributePropertyWriter.construct(attrName, propDef,
ac.getAnnotations(), type);
}
protected BeanPropertyWriter _constructVirtualProperty(JsonAppend.Prop prop,
MapperConfig<?> config, AnnotatedClass ac)
{
PropertyMetadata metadata = prop.required() ?
PropertyMetadata.STD_REQUIRED : PropertyMetadata.STD_OPTIONAL;
PropertyName propName = _propertyName(prop.name(), prop.namespace());
JavaType type = config.constructType(prop.type());
// now, then, we need a placeholder for member (no real Field/Method):
AnnotatedMember member = new VirtualAnnotatedMember(ac, ac.getRawType(),
propName.getSimpleName(), type.getRawClass());
// and with that and property definition
SimpleBeanPropertyDefinition propDef = SimpleBeanPropertyDefinition.construct(config,
member, propName, metadata, prop.include());
Class<?> implClass = prop.value();
HandlerInstantiator hi = config.getHandlerInstantiator();
VirtualBeanPropertyWriter bpw = (hi == null) ? null
: hi.virtualPropertyWriterInstance(config, implClass);
if (bpw == null) {
bpw = (VirtualBeanPropertyWriter) ClassUtil.createInstance(implClass,
config.canOverrideAccessModifiers());
}
// one more thing: give it necessary contextual information
return bpw.withConfig(config, ac, propDef, type);
}
/*
/**********************************************************
/* Serialization: property annotations
/**********************************************************
*/
@Override
public PropertyName findNameForSerialization(Annotated a)
{
String name = null;
JsonGetter jg = _findAnnotation(a, JsonGetter.class);
if (jg != null) {
name = jg.value();
} else {
JsonProperty pann = _findAnnotation(a, JsonProperty.class);
if (pann != null) {
name = pann.value();
} else if (_hasAnnotation(a, JsonSerialize.class) || _hasAnnotation(a, JsonView.class)) {
name = "";
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> else {
return null;
}
}
if (name.length() == 0) { // empty String means 'default'
return PropertyName.USE_DEFAULT;
}
return new PropertyName(name);
}
@Override
public boolean hasAsValueAnnotation(AnnotatedMethod am) {
JsonValue ann = _findAnnotation(am, JsonValue.class);
// value of 'false' means disabled...
return (ann != null && ann.value());
}
/*
/**********************************************************
/* Deserialization: general annotations
/**********************************************************
*/
@Override
public Class<? extends JsonDeserializer<?>> findDeserializer(Annotated a)
{
JsonDeserialize ann = _findAnnotation(a, JsonDeserialize.class);
if (ann != null) {
Class<? extends JsonDeserializer<?>> deserClass = ann.using();
if (deserClass != JsonDeserializer.None.class) {
return deserClass;
}
}
return null;
}
@Override
public Class<? extends KeyDeserializer> findKeyDeserializer(Annotated a)
{
JsonDeserialize ann = _findAnnotation(a, JsonDeserialize.class);
if (ann != null) {
Class<? extends KeyDeserializer> deserClass = ann.keyUsing();
if (deserClass != KeyDeserializer.None.class) {
return deserClass;
}
}
return null;
}
@Override
public Class<? extends JsonDeserializer<?>> findContentDeserializer(Annotated a)
{
JsonDeserialize ann = _findAnnotation(a, JsonDeserialize.class);
if (ann != null) {
Class<? extends JsonDeserializer<?>> deserClass = ann.contentUsing();
if (deserClass != JsonDeserializer.None.class) {
return deserClass;
}
}
return null;
}
@Override
public Class<?> findDeserializationType(Annotated am, JavaType baseType) {
JsonDeserialize ann = _findAnnotation(am, JsonDeserialize.class);
return (ann == null) ? null : _classIfExplicit(ann.as());
}
@Override
public Class<?> findDeserializationKeyType(Annotated am, JavaType baseKeyType) {
JsonDeserialize ann = _findAnnotation(am, JsonDeserialize.class);
return (ann == null) ? null : _classIfExplicit(ann.keyAs());
}
@Override
public Class<?> findDeserializationContentType(Annotated am, JavaType baseContentType)
{
JsonDeserialize ann = _findAnnotation(am, JsonDeserialize.class);
return (ann == null) ? null : _classIfExplicit(ann.contentAs());
}
@Override
public Object findDeserializationConverter(Annotated a)
{
JsonDeserialize ann = _findAnnotation(a, JsonDeserialize.class);
return (ann == null)
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> ? null : _classIfExplicit(ann.converter(), Converter.None.class);
}
@Override
public Object findDeserializationContentConverter(AnnotatedMember a)
{
JsonDeserialize ann = _findAnnotation(a, JsonDeserialize.class);
return (ann == null) ? null : _classIfExplicit(ann.contentConverter(), Converter.None.class);
}
/*
/**********************************************************
/* Deserialization: Class annotations
/**********************************************************
*/
@Override
public Object findValueInstantiator(AnnotatedClass ac)
{
JsonValueInstantiator ann = _findAnnotation(ac, JsonValueInstantiator.class);
// no 'null' marker yet, so:
return (ann == null) ? null : ann.value();
}
@Override
public Class<?> findPOJOBuilder(AnnotatedClass ac)
{
JsonDeserialize ann = _findAnnotation(ac, JsonDeserialize.class);
return (ann == null) ? null : _classIfExplicit(ann.builder());
}
@Override
public JsonPOJOBuilder.Value findPOJOBuilderConfig(AnnotatedClass ac)
{
JsonPOJOBuilder ann = _findAnnotation(ac, JsonPOJOBuilder.class);
return (ann == null) ? null : new JsonPOJOBuilder.Value(ann);
}
/*
/**********************************************************
/* Deserialization: property annotations
/**********************************************************
*/
@Override
public PropertyName findNameForDeserialization(Annotated a)
{
String name;
// @JsonSetter has precedence over @JsonProperty, being more specific
// @JsonDeserialize implies that there is a property, but no name
JsonSetter js = _findAnnotation(a, JsonSetter.class);
if (js != null) {
name = js.value();
} else {
JsonProperty pann = _findAnnotation(a, JsonProperty.class);
if (pann != null) {
name = pann.value();
/* 22-Apr-2014, tatu: Should figure out a better way to do this, but
* it's actually bit tricky to do it more efficiently (meta-annotations
* add more lookups; AnnotationMap costs etc)
*/
} else if (_hasAnnotation(a, JsonDeserialize.class)
|| _hasAnnotation(a, JsonView.class)
|| _hasAnnotation(a, JsonUnwrapped.class) // [#442]
|| _hasAnnotation(a, JsonBackReference.class)
|| _hasAnnotation(a, JsonManagedReference.class)) {
name = "";
} else {
return null;
}
}
if (name.length() == 0) { // empty String means 'default'
return PropertyName.USE_DEFAULT
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>;
}
return new PropertyName(name);
}
@Override
public boolean hasAnySetterAnnotation(AnnotatedMethod am)
{
/* No dedicated disabling; regular @JsonIgnore used
* if needs to be ignored (and if so, is handled prior
* to this method getting called)
*/
return _hasAnnotation(am, JsonAnySetter.class);
}
@Override
public boolean hasAnyGetterAnnotation(AnnotatedMethod am)
{
/* No dedicated disabling; regular @JsonIgnore used
* if needs to be ignored (handled separately
*/
return _hasAnnotation(am, JsonAnyGetter.class);
}
@Override
public boolean hasCreatorAnnotation(Annotated a)
{
/* No dedicated disabling; regular @JsonIgnore used
* if needs to be ignored (and if so, is handled prior
* to this method getting called)
*/
JsonCreator ann = _findAnnotation(a, JsonCreator.class);
return (ann != null && ann.mode() != JsonCreator.Mode.DISABLED);
}
@Override
public JsonCreator.Mode findCreatorBinding(Annotated a) {
JsonCreator ann = _findAnnotation(a, JsonCreator.class);
return (ann == null) ? null : ann.mode();
}
/*
/**********************************************************
/* Helper methods
/**********************************************************
*/
protected boolean _isIgnorable(Annotated a)
{
JsonIgnore ann = _findAnnotation(a, JsonIgnore.class);
return (ann != null && ann.value());
}
protected Class<?> _classIfExplicit(Class<?> cls) {
if (cls == null || ClassUtil.isBogusClass(cls)) {
return null;
}
return cls;
}
protected Class<?> _classIfExplicit(Class<?> cls, Class<?> implicit) {
cls = _classIfExplicit(cls);
return (cls == null || cls == implicit) ? null : cls;
}
protected PropertyName _propertyName(String localName, String namespace) {
if (localName.isEmpty()) {
return PropertyName.USE_DEFAULT;
}
if (namespace == null || namespace.isEmpty()) {
return new PropertyName(localName);
}
return new PropertyName(localName, namespace);
}
/**
* Helper method called to construct and initialize instance of {@link TypeResolverBuilder}
* if given annotated element indicates one is needed.
*/
@SuppressWarnings("deprecation")
protected TypeResolverBuilder<?> _findTypeResolver(MapperConfig<?> config,
Annotated ann, JavaType baseType)
{
// First: maybe we have explicit type resolver?
TypeResolverBuilder<?> b;
JsonTypeInfo info = _findAnnotation(ann, JsonTypeInfo.class);
JsonTypeResolver resAnn = _find
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Annotation(ann, JsonTypeResolver.class);
if (resAnn != null) {
if (info == null) {
return null;
}
/* let's not try to force access override (would need to pass
* settings through if we did, since that's not doable on some
* platforms)
*/
b = config.typeResolverBuilderInstance(ann, resAnn.value());
} else { // if not, use standard one, if indicated by annotations
if (info == null) {
return null;
}
// bit special; must return 'marker' to block use of default typing:
if (info.use() == JsonTypeInfo.Id.NONE) {
return _constructNoTypeResolverBuilder();
}
b = _constructStdTypeResolverBuilder();
}
// Does it define a custom type id resolver?
JsonTypeIdResolver idResInfo = _findAnnotation(ann, JsonTypeIdResolver.class);
TypeIdResolver idRes = (idResInfo == null) ? null
: config.typeIdResolverInstance(ann, idResInfo.value());
if (idRes != null) { // [JACKSON-359]
idRes.init(baseType);
}
b = b.init(info.use(), idRes);
/* 13-Aug-2011, tatu: One complication wrt [JACKSON-453]; external id
* only works for properties; so if declared for a Class, we will need
* to map it to "PROPERTY" instead of "EXTERNAL_PROPERTY"
*/
JsonTypeInfo.As inclusion = info.include();
if (inclusion == JsonTypeInfo.As.EXTERNAL_PROPERTY && (ann instanceof AnnotatedClass)) {
inclusion = JsonTypeInfo.As.PROPERTY;
}
b = b.inclusion(inclusion);
b = b.typeProperty(info.property());
Class<?> defaultImpl = info.defaultImpl();
// 08-Dec-2014, tatu: To deprecated `JsonTypeInfo.None` we need to use other placeholder(s);
// and since `java.util.Void` has other purpose (to indicate "deser as null"), we'll instead
// use `JsonTypeInfo.class` itself. But any annotation type will actually do, as they have no
// valid use (can not instantiate as default)
if (defaultImpl != JsonTypeInfo.None.class && !defaultImpl.isAnnotation()) {
b = b.defaultImpl(defaultImpl);
}
b = b.typeIdVisibility(info.visible());
return b;
}
/**
* Helper method for constructing standard {@link TypeResolverBuilder}
* implementation.
*/
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> DeserializerCache _cache;
/*
/**********************************************************
/* Configuration, changeable via fluent factories
/**********************************************************
*/
/**
* Read-only factory instance; exposed to let
* owners (<code>ObjectMapper</code>, <code>ObjectReader</code>)
* access it.
*/
protected final DeserializerFactory _factory;
/*
/**********************************************************
/* Configuration that gets set for instances (not blueprints)
/* (partly denormalized for performance)
/**********************************************************
*/
/**
* Generic deserialization processing configuration
*/
protected final DeserializationConfig _config;
/**
* Bitmap of {@link DeserializationFeature}s that are enabled
*/
protected final int _featureFlags;
/**
* Currently active view, if any.
*/
protected final Class<?> _view;
/**
* Currently active parser used for deserialization.
* May be different from the outermost parser
* when content is buffered.
*/
protected transient JsonParser _parser;
/**
* Object used for resolving references to injectable
* values.
*/
protected final InjectableValues _injectableValues;
/*
/**********************************************************
/* Per-operation reusable helper objects (not for blueprints)
/**********************************************************
*/
protected transient ArrayBuilders _arrayBuilders;
protected transient ObjectBuffer _objectBuffer;
protected transient DateFormat _dateFormat;
/**
* Lazily-constructed holder for per-call attributes.
*
* @since 2.3
*/
protected transient ContextAttributes _attributes;
/**
* Type of {@link JsonDeserializer} (or, more specifically,
* {@link ContextualizableDeserializer}) that is being
* contextualized currently.
*
* @since 2.5
*/
protected LinkedNode<JavaType> _currentType;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
protected DeserializationContext(DeserializerFactory df) {
this(df, null);
}
protected DeserializationContext(DeserializerFactory df,
DeserializerCache cache)
{
if (df == null) {
throw new IllegalArgumentException("Can not pass null DeserializerFactory");
}
_factory = df;
_cache = (cache == null) ? new DeserializerCache() : cache;
_featureFlags = 0;
_config = null;
_injectableValues = null;
_view = null;
_attributes = null;
}
protected DeserializationContext(DeserializationContext src,
DeserializerFactory factory)
{
_cache = src._cache;
_factory = factory;
_config = src._config;
_featureFlags = src._featureFlags;
_view = src._view;
_parser = src._parser
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>;
_injectableValues = src._injectableValues;
_attributes = src._attributes;
}
/**
* Constructor used for creating actual per-call instances.
*/
protected DeserializationContext(DeserializationContext src,
DeserializationConfig config, JsonParser p,
InjectableValues injectableValues)
{
_cache = src._cache;
_factory = src._factory;
_config = config;
_featureFlags = config.getDeserializationFeatures();
_view = config.getActiveView();
_parser = p;
_injectableValues = injectableValues;
_attributes = config.getAttributes();
}
/**
* Copy-constructor for use with <code>copy()</code> by {@link ObjectMapper#copy()}
*/
protected DeserializationContext(DeserializationContext src) {
_cache = new DeserializerCache();
_factory = src._factory;
_config = src._config;
_featureFlags = src._featureFlags;
_view = src._view;
_injectableValues = null;
}
/*
/**********************************************************
/* DatabindContext implementation
/**********************************************************
*/
@Override
public DeserializationConfig getConfig() { return _config; }
@Override
public final Class<?> getActiveView() { return _view; }
@Override
public final AnnotationIntrospector getAnnotationIntrospector() {
return _config.getAnnotationIntrospector();
}
@Override
public final TypeFactory getTypeFactory() {
return _config.getTypeFactory();
}
/*
/**********************************************************
/* Access to per-call state, like generic attributes (2.3+)
/**********************************************************
*/
@Override
public Object getAttribute(Object key) {
return _attributes.getAttribute(key);
}
@Override
public DeserializationContext setAttribute(Object key, Object value)
{
_attributes = _attributes.withPerCallAttribute(key, value);
return this;
}
/**
* Accessor to {@link JavaType} of currently contextualized
* {@link ContextualDeserializer}, if any.
* This is sometimes useful for generic {@link JsonDeserializer}s that
* do not get passed (or do not retain) type information when being
* constructed: happens for example for deserializers constructed
* from annotations.
*
* @since 2.5
*
* @return Type of {@link ContextualDeserializer} being contextualized,
* if process is on-going; null if not.
*/
public JavaType getContextualType() {
return (_currentType == null) ? null : _currentType.value();
}
/*
/**********************************************************
/* Public API, config setting accessors
/**********************************************************
*/
/**
* Method for getting current {@
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> (JsonDeserializer<Object>) handleSecondaryContextualization(deser, null, type);
TypeDeserializer typeDeser = _factory.findTypeDeserializer(_config, type);
if (typeDeser != null) {
// important: contextualize to indicate this is for root value
typeDeser = typeDeser.forProperty(null);
return new TypeWrappedDeserializer(typeDeser, deser);
}
return deser;
}
/**
* Convenience method, functionally same as:
*<pre>
* getDeserializerProvider().findKeyDeserializer(getConfig(), prop.getType(), prop);
*</pre>
*/
public final KeyDeserializer findKeyDeserializer(JavaType keyType,
BeanProperty prop) throws JsonMappingException {
KeyDeserializer kd = _cache.findKeyDeserializer(this,
_factory, keyType);
// Second: contextualize?
if (kd instanceof ContextualKeyDeserializer) {
kd = ((ContextualKeyDeserializer) kd).createContextual(this, prop);
}
return kd;
}
/*
/**********************************************************
/* Public API, ObjectId handling
/**********************************************************
*/
/**
* Method called to find and return entry corresponding to given
* Object Id: will add an entry if necessary, and never returns null
*/
public abstract ReadableObjectId findObjectId(Object id, ObjectIdGenerator<?> generator, ObjectIdResolver resolver);
@Deprecated // since 2.4
public abstract ReadableObjectId findObjectId(Object id, ObjectIdGenerator<?> generator);
/**
* Method called to ensure that every object id encounter during processing
* are resolved.
*
* @throws UnresolvedForwardReference
*/
public abstract void checkUnresolvedObjectId()
throws UnresolvedForwardReference;
/*
/**********************************************************
/* Public API, type handling
/**********************************************************
*/
/**
* Convenience method, functionally equivalent to:
*<pre>
* getConfig().constructType(cls);
* </pre>
*/
public final JavaType constructType(Class<?> cls) {
return _config.constructType(cls);
}
/**
* Helper method to use for locating Class for given name. Should be used
* instead of basic <code>Class.forName(className);</code> as it can
* try using contextual class loader, or use platform-specific workarounds
* (like on Android, GAE).
*/
public Class<?> findClass(String className) throws ClassNotFoundException
{
// By default, delegate to ClassUtil: can be overridden with custom handling
return ClassUtil.findClass(className);
}
/*
/**********************************************************
/* Public API, helper object recycling
/**********************************************************
*/
/**
* Method that can be used to get access to
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> {
// 08-Jan-2008, tatu: not optimal, but should work for the most part; let's revise as needed.
Calendar c = Calendar.getInstance(getTimeZone());
c.setTime(d);
return c;
}
/*
/**********************************************************
/* Convenience methods for reading parsed values
/**********************************************************
*/
/**
* Convenience method that may be used by composite or container deserializers,
* for reading one-off values contained (for sequences, it is more efficient
* to actually fetch deserializer once for the whole collection).
*<p>
* NOTE: when deserializing values of properties contained in composite types,
* rather use {@link #readPropertyValue(JsonParser, BeanProperty, Class)};
* this method does not allow use of contextual annotations.
*
* @since 2.4
*/
public <T> T readValue(JsonParser p, Class<T> type) throws IOException {
return readValue(p, getTypeFactory().constructType(type));
}
/**
* @since 2.4
*/
@SuppressWarnings("unchecked")
public <T> T readValue(JsonParser p, JavaType type) throws IOException {
JsonDeserializer<Object> deser = findRootValueDeserializer(type);
if (deser == null) {
}
return (T) deser.deserialize(p, this);
}
/**
* Convenience method that may be used by composite or container deserializers,
* for reading one-off values for the composite type, taking into account
* annotations that the property (passed to this method -- usually property that
* has custom serializer that called this method) has.
*
* @since 2.4
*/
public <T> T readPropertyValue(JsonParser p, BeanProperty prop, Class<T> type) throws IOException {
return readPropertyValue(p, prop, getTypeFactory().constructType(type));
}
/**
* @since 2.4
*/
@SuppressWarnings("unchecked")
public <T> T readPropertyValue(JsonParser p, BeanProperty prop, JavaType type) throws IOException {
JsonDeserializer<Object> deser = findContextualValueDeserializer(type, prop);
if (deser == null) {
}
return (T) deser.deserialize(p, this);
}
/*
/**********************************************************
/* Methods for problem handling, reporting
/**********************************************************
*/
/**
* Method deserializers can call to inform configured {@link DeserializationProblemHandler}s
* of an unrecognized property.
*
* @return True if there was a configured problem handler that was able to handle the
* problem
*/
/**
* Method deserializers can call to inform configured {@link DeserializationProblem
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Handler}s
* of an unrecognized property.
*/
public boolean handleUnknownProperty(JsonParser p, JsonDeserializer<?> deser,
Object instanceOrClass, String propName)
throws IOException, JsonProcessingException
{
LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers();
if (h != null) {
while (h != null) {
// Can bail out if it's handled
if (h.value().handleUnknownProperty(this, p, deser, instanceOrClass, propName)) {
return true;
}
h = h.next();
}
}
return false;
}
/**
* Helper method for reporting a problem with unhandled unknown exception
*
* @param instanceOrClass Either value being populated (if one has been
* instantiated), or Class that indicates type that would be (or
* have been) instantiated
* @param deser Deserializer that had the problem, if called by deserializer
* (or on behalf of one)
*/
public void reportUnknownProperty(Object instanceOrClass, String fieldName,
JsonDeserializer<?> deser)
throws JsonMappingException
{
if (!isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) {
return;
}
// Do we know properties that are expected instead?
Collection<Object> propIds = (deser == null) ? null : deser.getKnownPropertyNames();
throw UnrecognizedPropertyException.from(_parser,
instanceOrClass, fieldName, propIds);
}
/*
/**********************************************************
/* Methods for constructing exceptions
/**********************************************************
*/
/**
* Helper method for constructing generic mapping exception for specified type
*/
public JsonMappingException mappingException(Class<?> targetClass) {
return mappingException(targetClass, _parser.getCurrentToken());
}
public JsonMappingException mappingException(Class<?> targetClass, JsonToken token) {
return JsonMappingException.from(_parser, "Can not deserialize instance of "+_calcName(targetClass)+" out of "+token+" token");
}
/**
* Helper method for constructing generic mapping exception with specified
* message and current location information
*/
public JsonMappingException mappingException(String message) {
return JsonMappingException.from(getParser(), message);
}
/**
* Helper method for constructing instantiation exception for specified type,
* to indicate problem with physically constructing instance of
* specified class (missing constructor, exception from constructor)
*/
public JsonMappingException instantiationException(Class<?> instClass, Throwable t) {
return JsonMappingException.from(_parser,
"Can not construct instance of "+instClass.getName()+", problem: "+t.getMessage(), t);
}
public JsonMappingException instantiationException(Class<?> instClass, String msg) {
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
return JsonMappingException.from(_parser, "Can not construct instance of "+instClass.getName()+", problem: "+msg);
}
/**
* Method that will construct an exception suitable for throwing when
* some String values are acceptable, but the one encountered is not.
*
*
* @deprecated Since 2.1 should use variant that takes value
*/
@Deprecated
public JsonMappingException weirdStringException(Class<?> instClass, String msg) {
return weirdStringException(null, instClass, msg);
}
/**
* Method that will construct an exception suitable for throwing when
* some String values are acceptable, but the one encountered is not.
*
* @param value String value from input being deserialized
* @param instClass Type that String should be deserialized into
* @param msg Message that describes specific problem
*
* @since 2.1
*/
public JsonMappingException weirdStringException(String value, Class<?> instClass, String msg) {
return InvalidFormatException.from(_parser,
"Can not construct instance of "+instClass.getName()+" from String value '"+_valueDesc()+"': "+msg,
value, instClass);
}
/**
* Helper method for constructing exception to indicate that input JSON
* Number was not suitable for deserializing into given type.
*/
@Deprecated
public JsonMappingException weirdNumberException(Class<?> instClass, String msg) {
return weirdStringException(null, instClass, msg);
}
/**
* Helper method for constructing exception to indicate that input JSON
* Number was not suitable for deserializing into given target type.
*/
public JsonMappingException weirdNumberException(Number value, Class<?> instClass, String msg) {
return InvalidFormatException.from(_parser,
"Can not construct instance of "+instClass.getName()+" from number value ("+_valueDesc()+"): "+msg,
null, instClass);
}
/**
* Helper method for constructing exception to indicate that given JSON
* Object field name was not in format to be able to deserialize specified
* key type.
*/
public JsonMappingException weirdKeyException(Class<?> keyClass, String keyValue, String msg) {
return InvalidFormatException.from(_parser,
"Can not construct Map key of type "+keyClass.getName()+" from String \""+_desc(keyValue)+"\": "+msg,
keyValue, keyClass);
}
/**
* Helper method for indicating that the current token was expected to be another
* token.
*/
public JsonMappingException wrongTokenException(JsonParser p, JsonToken expToken, String msg0) {
String msg = "Unexpected token ("+p.getCurrentToken()+"), expected "+expToken;
if (msg0 != null) {
msg = msg +
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> ": "+msg0;
}
return JsonMappingException.from(p, msg);
}
/**
* Helper method for constructing exception to indicate that given
* type id (parsed from JSON) could not be converted to a Java type.
*/
@Deprecated // since 2.5, use overloaded variant
public JsonMappingException unknownTypeException(JavaType type, String id) {
return JsonMappingException.from(_parser, "Could not resolve type id '"+id+"' into a subtype of "+type);
}
/**
* @since 2.5
*/
public JsonMappingException unknownTypeException(JavaType type, String id,
String extraDesc) {
String msg = "Could not resolve type id '"+id+"' into a subtype of "+type;
if (extraDesc != null) {
msg = msg + ": "+extraDesc;
}
return JsonMappingException.from(_parser, msg);
}
public JsonMappingException endOfInputException(Class<?> instClass) {
return JsonMappingException.from(_parser, "Unexpected end-of-input when trying to deserialize a "
+instClass.getName());
}
/*
/**********************************************************
/* Overridable internal methods
/**********************************************************
*/
protected DateFormat getDateFormat()
{
if (_dateFormat != null) {
return _dateFormat;
}
/* 24-Feb-2012, tatu: At this point, all timezone configuration
* should have occurred, with respect to default dateformat
* and timezone configuration. But we still better clone
* an instance as formatters may be stateful.
*/
DateFormat df = _config.getDateFormat();
_dateFormat = df = (DateFormat) df.clone();
return df;
}
protected String determineClassName(Object instance) {
return ClassUtil.getClassDescription(instance);
}
/*
/**********************************************************
/* Other internal methods
/**********************************************************
*/
protected String _calcName(Class<?> cls) {
if (cls.isArray()) {
return _calcName(cls.getComponentType())+"[]";
}
return cls.getName();
}
protected String _valueDesc() {
try {
return _desc(_parser.getText());
} catch (Exception e) {
return "[N/A]";
}
}
protected String _desc(String desc) {
// !!! should we quote it? (in case there are control chars, linefeeds)
if (desc.length() > MAX_ERROR_STR_LEN) {
desc = desc.substring(0, MAX_ERROR_STR_LEN) + "]...[" + desc.substring(desc.length() - MAX_ERROR_STR_LEN);
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> Method _accessorMethod;
/**
* Field that contains the property value for field-accessible
* properties.
* Null if and only if {@link #_accessorMethod} is null.
*/
protected final Field _field;
/*
/**********************************************************
/* Opaque internal data that bean serializer factory and
/* bean serializers can add.
/**********************************************************
*/
protected HashMap<Object,Object> _internalSettings;
/*
/**********************************************************
/* Serialization settings
/**********************************************************
*/
/**
* Logical name of the property; will be used as the field name
* under which value for the property is written.
*<p>
* NOTE: do NOT change name of this field; it is accessed by
* Afterburner module (until 2.4; not directly from 2.5)
* ALSO NOTE: ... and while it really ought to be `SerializableString`,
* changing that is also binary-incompatible change. So nope.
*/
protected final SerializedString _name;
/**
* Wrapper name to use for this element, if any
*
* @since 2.2
*/
protected final PropertyName _wrapperName;
/**
* Type to use for locating serializer; normally same as return
* type of the accessor method, but may be overridden by annotations.
*/
protected final JavaType _cfgSerializationType;
/**
* Serializer to use for writing out the value: null if it can not
* be known statically; non-null if it can.
*/
protected JsonSerializer<Object> _serializer;
/**
* Serializer used for writing out null values, if any: if null,
* null values are to be suppressed.
*/
protected JsonSerializer<Object> _nullSerializer;
/**
* In case serializer is not known statically (i.e. <code>_serializer</code>
* is null), we will use a lookup structure for storing dynamically
* resolved mapping from type(s) to serializer(s).
*/
protected transient PropertySerializerMap _dynamicSerializers;
/**
* Whether null values are to be suppressed (nothing written out if
* value is null) or not.
*/
protected final boolean _suppressNulls;
/**
* Value that is considered default value of the property; used for
* default-value-suppression if enabled.
*/
protected final Object _suppressableValue;
/**
* Alternate set of property writers used when view-based filtering
* is available for the Bean.
*/
protected final Class<?>[] _includeInViews;
/**
* If property being serialized needs type information to be
* included this is the type serializer to use.
* Declared type (possibly augmented with annotations) of property
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>A extends Annotation> A getAnnotation(Class<A> acls) {
return (_member == null) ? null : _member.getAnnotation(acls);
}
// Note: also part of 'PropertyWriter'
@Override
public <A extends Annotation> A getContextAnnotation(Class<A> acls) {
return (_contextAnnotations == null) ? null : _contextAnnotations.get(acls);
}
@Override public AnnotatedMember getMember() { return _member; }
// @since 2.3 -- needed so it can be overridden by unwrapping writer
protected void _depositSchemaProperty(ObjectNode propertiesNode, JsonNode schemaNode) {
propertiesNode.set(getName(), schemaNode);
}
/**
* Note: will be defined in {@link BeanProperty}; as of now is not yet.
*<p>
* TODO: move to {@link BeanProperty} in near future, once all standard
* implementations define it.
*
* @since 2.5
*/
public boolean isVirtual() { return false; }
/*
/**********************************************************
/* Managing and accessing of opaque internal settings
/* (used by extensions)
/**********************************************************
*/
/**
* Method for accessing value of specified internal setting.
*
* @return Value of the setting, if any; null if none.
*/
public Object getInternalSetting(Object key) {
return (_internalSettings == null) ? null : _internalSettings.get(key);
}
/**
* Method for setting specific internal setting to given value
*
* @return Old value of the setting, if any (null if none)
*/
public Object setInternalSetting(Object key, Object value) {
if (_internalSettings == null) {
_internalSettings = new HashMap<Object,Object>();
}
return _internalSettings.put(key, value);
}
/**
* Method for removing entry for specified internal setting.
*
* @return Existing value of the setting, if any (null if none)
*/
public Object removeInternalSetting(Object key) {
Object removed = null;
if (_internalSettings != null) {
removed = _internalSettings.remove(key);
// to reduce memory usage, let's also drop the Map itself, if empty
if (_internalSettings.size() == 0) {
_internalSettings = null;
}
}
return removed;
}
/*
/**********************************************************
/* Accessors
/**********************************************************
*/
public SerializableString getSerializedName() { return _name; }
public boolean hasSerializer() { return _serializer != null; }
public boolean hasNullSerializer() { return _nullSerializer != null; }
/**
* Accessor that will return true if this bean
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> property has to support
* "unwrapping"; ability to replace POJO structural wrapping with optional
* name prefix and/or suffix (or in some cases, just removal of wrapper name).
*<p>
* Default implementation simply returns false.
*
* @since 2.3
*/
public boolean isUnwrapping() { return false; }
public boolean willSuppressNulls() { return _suppressNulls; }
// Needed by BeanSerializer#getSchema
public JsonSerializer<Object> getSerializer() { return _serializer; }
public JavaType getSerializationType() { return _cfgSerializationType; }
public Class<?> getRawSerializationType() {
return (_cfgSerializationType == null) ? null : _cfgSerializationType.getRawClass();
}
public Class<?> getPropertyType() {
return (_accessorMethod != null) ? _accessorMethod.getReturnType() : _field.getType();
}
/**
* Get the generic property type of this property writer.
*
* @return The property type, or null if not found.
*/
public Type getGenericPropertyType() {
if (_accessorMethod != null) {
return _accessorMethod.getGenericReturnType();
}
if (_field != null) {
return _field.getGenericType();
}
return null;
}
public Class<?>[] getViews() { return _includeInViews; }
/*
/**********************************************************
/* PropertyWriter methods (serialization)
/**********************************************************
*/
/**
* Method called to access property that this bean stands for, from
* within given bean, and to serialize it as a JSON Object field
* using appropriate serializer.
*/
@Override
public void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
{
// inlined 'get()'
final Object value = (_accessorMethod == null) ? _field.get(bean) : _accessorMethod.invoke(bean);
// Null handling is bit different, check that first
if (value == null) {
if (_nullSerializer != null) {
gen.writeFieldName(_name);
_nullSerializer.serialize(null, gen, prov);
}
return;
}
// then find serializer to use
JsonSerializer<Object> ser = _serializer;
if (ser == null) {
Class<?> cls = value.getClass();
PropertySerializerMap m = _dynamicSerializers;
ser = m.serializerFor(cls);
if (ser == null) {
ser = _findAndAddDynamic(m, cls, prov);
}
}
// and then see if we must suppress certain values (default, empty)
if (_suppressableValue != null) {
if (MARKER_FOR_EMPTY == _suppressableValue) {
if (ser.isEmpty
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>(prov, value)) {
return;
}
} else if (_suppressableValue.equals(value)) {
return;
}
}
// For non-nulls: simple check for direct cycles
if (value == bean) {
// three choices: exception; handled by call; or pass-through
if (_handleSelfReference(bean, gen, prov, ser)) {
return;
}
}
gen.writeFieldName(_name);
if (_typeSerializer == null) {
ser.serialize(value, gen, prov);
} else {
ser.serializeWithType(value, gen, prov, _typeSerializer);
}
}
/**
* Method called to indicate that serialization of a field was omitted
* due to filtering, in cases where backend data format does not allow
* basic omission.
*
* @since 2.3
*/
@Override
public void serializeAsOmittedField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
{
if (!gen.canOmitFields()) {
gen.writeOmittedField(_name.getValue());
}
}
/**
* Alternative to {@link #serializeAsField} that is used when a POJO
* is serialized as JSON Array; the difference is that no field names
* are written.
*
* @since 2.3
*/
@Override
public void serializeAsElement(Object bean, JsonGenerator gen, SerializerProvider prov)
throws Exception
{
// inlined 'get()'
final Object value = (_accessorMethod == null) ? _field.get(bean) : _accessorMethod.invoke(bean);
if (value == null) { // nulls need specialized handling
if (_nullSerializer != null) {
_nullSerializer.serialize(null, gen, prov);
} else { // can NOT suppress entries in tabular output
gen.writeNull();
}
return;
}
// otherwise find serializer to use
JsonSerializer<Object> ser = _serializer;
if (ser == null) {
Class<?> cls = value.getClass();
PropertySerializerMap map = _dynamicSerializers;
ser = map.serializerFor(cls);
if (ser == null) {
ser = _findAndAddDynamic(map, cls, prov);
}
}
// and then see if we must suppress certain values (default, empty)
if (_suppressableValue != null) {
if (MARKER_FOR_EMPTY == _suppressableValue) {
if (ser.isEmpty(prov, value)) { // can NOT suppress entries in tabular output
serializeAsPlaceholder(bean, gen, prov);
return;
}
} else if (_suppressableValue.equals(value)) { // can NOT suppress entries in
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>) ser).getSchema(provider, hint, isOptional) ;
} else {
schemaNode = com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode();
}
_depositSchemaProperty(propertiesNode, schemaNode);
}
/*
/**********************************************************
/* Helper methods
/**********************************************************
*/
protected JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
Class<?> type, SerializerProvider provider) throws JsonMappingException
{
PropertySerializerMap.SerializerAndMapResult result;
if (_nonTrivialBaseType != null) {
JavaType t = provider.constructSpecializedType(_nonTrivialBaseType, type);
result = map.findAndAddPrimarySerializer(t, provider, this);
} else {
result = map.findAndAddPrimarySerializer(type, provider, this);
}
// did we get a new map of serializers? If so, start using it
if (map != result.map) {
_dynamicSerializers = result.map;
}
return result.serializer;
}
/**
* Method that can be used to access value of the property this
* Object describes, from given bean instance.
*<p>
* Note: method is final as it should not need to be overridden -- rather,
* calling method(s) ({@link #serializeAsField}) should be overridden
* to change the behavior
*/
public final Object get(Object bean) throws Exception {
return (_accessorMethod == null) ? _field.get(bean) : _accessorMethod.invoke(bean);
}
/**
* Method called to handle a direct self-reference through this property.
* Method can choose to indicate an error by throwing {@link JsonMappingException};
* fully handle serialization (and return true); or indicate that it should be
* serialized normally (return false).
*<p>
* Default implementation will throw {@link JsonMappingException} if
* {@link SerializationFeature#FAIL_ON_SELF_REFERENCES} is enabled;
* or return <code>false</code> if it is disabled.
*
* @return True if method fully handled self-referential value; false if not (caller
* is to handle it) or {@link JsonMappingException} if there is no way handle it
*/
protected boolean _handleSelfReference(Object bean, JsonGenerator gen, SerializerProvider prov, JsonSerializer<?> ser)
throws JsonMappingException {
if (prov.isEnabled(SerializationFeature.FAIL_ON_SELF_REFERENCES)
&& !ser.usesObjectId()) {
// 05-Feb-2013, tatu: Usually a problem, but NOT if we are handling
// object id; this may be the case for BeanSerializers at
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashSet;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
/**
* Container class for deserializers that handle core JDK primitive
* (and matching wrapper) types, as well as standard "big" numeric types.
* Note that this includes types such as {@link java.lang.Boolean}
* and {@link java.lang.Character} which are not strictly numeric,
* but are part of primitive/wrapper types.
*/
public class NumberDeserializers
{
private final static HashSet<String> _classNames = new HashSet<String>();
static {
// note: can skip primitive types; other ways to check them:
Class<?>[] numberTypes = new Class<?>[] {
Boolean.class,
Byte.class,
Short.class,
Character.class,
Integer.class,
Long.class,
Float.class,
Double.class,
// and more generic ones
Number.class, BigDecimal.class, BigInteger.class
};
for (Class<?> cls : numberTypes) {
_classNames.add(cls.getName());
}
}
public static JsonDeserializer<?> find(Class<?> rawType, String clsName) {
if (rawType.isPrimitive()) {
if (rawType == Integer.TYPE) {
return IntegerDeserializer.primitiveInstance;
}
if (rawType == Boolean.TYPE) {
return BooleanDeserializer.primitiveInstance;
}
if (rawType == Long.TYPE) {
return LongDeserializer.primitiveInstance;
}
if (rawType == Double.TYPE) {
return DoubleDeserializer.primitiveInstance;
}
if (rawType == Character.TYPE) {
return CharacterDeserializer.primitiveInstance;
}
if (rawType == Byte.TYPE) {
return ByteDeserializer.primitiveInstance;
}
if (rawType == Short.TYPE) {
return ShortDeserializer.primitiveInstance;
}
if (rawType == Float.TYPE) {
return FloatDeserializer.primitiveInstance;
}
} else if (_classNames.contains(clsName)) {
// Start with most common types; int, boolean
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>, long, double
if (rawType == Integer.class) {
return IntegerDeserializer.wrapperInstance;
}
if (rawType == Boolean.class) {
return BooleanDeserializer.wrapperInstance;
}
if (rawType == Long.class) {
return LongDeserializer.wrapperInstance;
}
if (rawType == Double.class) {
return DoubleDeserializer.wrapperInstance;
}
if (rawType == Character.class) {
return CharacterDeserializer.wrapperInstance;
}
if (rawType == Byte.class) {
return ByteDeserializer.wrapperInstance;
}
if (rawType == Short.class) {
return ShortDeserializer.wrapperInstance;
}
if (rawType == Float.class) {
return FloatDeserializer.wrapperInstance;
}
if (rawType == Number.class) {
return NumberDeserializer.instance;
}
if (rawType == BigDecimal.class) {
return BigDecimalDeserializer.instance;
}
if (rawType == BigInteger.class) {
return BigIntegerDeserializer.instance;
}
} else {
return null;
}
// should never occur
throw new IllegalArgumentException("Internal error: can't find deserializer for "+rawType.getName());
}
/*
/**********************************************************
/* Then one intermediate base class for things that have
/* both primitive and wrapper types
/**********************************************************
*/
protected abstract static class PrimitiveOrWrapperDeserializer<T>
extends StdScalarDeserializer<T>
{
private static final long serialVersionUID = 1L;
protected final T _nullValue;
protected PrimitiveOrWrapperDeserializer(Class<T> vc, T nvl) {
super(vc);
_nullValue = nvl;
}
@Override
public final T getNullValue() {
return _nullValue;
}
}
/*
/**********************************************************
/* Then primitive/wrapper types
/**********************************************************
*/
@JacksonStdImpl
public final static class BooleanDeserializer
extends PrimitiveOrWrapperDeserializer<Boolean>
{
private static final long serialVersionUID = 1L;
final static BooleanDeserializer primitiveInstance = new BooleanDeserializer(Boolean.class, Boolean.FALSE);
final static BooleanDeserializer wrapperInstance = new BooleanDeserializer(Boolean.TYPE, null);
public BooleanDeserializer(Class<Boolean> cls, Boolean nvl)
{
super(cls, nvl);
}
@Override
public Boolean deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
return _parseBoolean(jp, ctxt);
}
// 1.6: since we can never have type info ("natural type"; String, Boolean, Integer, Double):
// (is it an error to even call this version?)
@Override
public Boolean deserializeWithType(JsonParser
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> jp, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException, JsonProcessingException
{
return _parseBoolean(jp, ctxt);
}
}
@JacksonStdImpl
public static class ByteDeserializer
extends PrimitiveOrWrapperDeserializer<Byte>
{
private static final long serialVersionUID = 1L;
final static ByteDeserializer primitiveInstance = new ByteDeserializer(Byte.TYPE, (byte) 0);
final static ByteDeserializer wrapperInstance = new ByteDeserializer(Byte.class, null);
public ByteDeserializer(Class<Byte> cls, Byte nvl)
{
super(cls, nvl);
}
@Override
public Byte deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
return _parseByte(jp, ctxt);
}
}
@JacksonStdImpl
public static class ShortDeserializer
extends PrimitiveOrWrapperDeserializer<Short>
{
private static final long serialVersionUID = 1L;
final static ShortDeserializer primitiveInstance = new ShortDeserializer(Short.class, Short.valueOf((short)0));
final static ShortDeserializer wrapperInstance = new ShortDeserializer(Short.TYPE, null);
public ShortDeserializer(Class<Short> cls, Short nvl)
{
super(cls, nvl);
}
@Override
public Short deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
return _parseShort(jp, ctxt);
}
}
@JacksonStdImpl
public static class CharacterDeserializer
extends PrimitiveOrWrapperDeserializer<Character>
{
private static final long serialVersionUID = 1L;
final static CharacterDeserializer primitiveInstance = new CharacterDeserializer(Character.class, '\0');
final static CharacterDeserializer wrapperInstance = new CharacterDeserializer(Character.TYPE, null);
public CharacterDeserializer(Class<Character> cls, Character nvl)
{
super(cls, nvl);
}
@Override
public Character deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_NUMBER_INT) { // ok iff ascii value
int value = jp.getIntValue();
if (value >= 0 && value <= 0xFFFF) {
return Character.valueOf((char) value);
}
} else if (t == JsonToken.VALUE_STRING) { // this is the usual type
// But does it have to be exactly one char?
String text = jp.getText();
if (text.length() == 1) {
return Character.valueOf(text.charAt(0));
}
// actually, empty should become null?
if (text.length() == 0) {
return (
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Character) getEmptyValue();
}
} else if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
//Issue#381
jp.nextToken();
final Character value = deserialize(jp, ctxt);
if (jp.nextToken() != JsonToken.END_ARRAY) {
throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY,
"Attempted to unwrap single value array for single '" + _valueClass.getName() + "' value but there was more than a single value in the array"
);
}
return value;
}
throw ctxt.mappingException(_valueClass, t);
}
}
@JacksonStdImpl
public final static class IntegerDeserializer
extends PrimitiveOrWrapperDeserializer<Integer>
{
private static final long serialVersionUID = 1L;
final static IntegerDeserializer primitiveInstance = new IntegerDeserializer(Integer.class, 0);
final static IntegerDeserializer wrapperInstance = new IntegerDeserializer(Integer.TYPE, null);
public IntegerDeserializer(Class<Integer> cls, Integer nvl)
{
super(cls, nvl);
}
@Override
public Integer deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
return _parseInteger(jp, ctxt);
}
// 1.6: since we can never have type info ("natural type"; String, Boolean, Integer, Double):
// (is it an error to even call this version?)
@Override
public Integer deserializeWithType(JsonParser jp, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException, JsonProcessingException
{
return _parseInteger(jp, ctxt);
}
}
@JacksonStdImpl
public final static class LongDeserializer
extends PrimitiveOrWrapperDeserializer<Long>
{
private static final long serialVersionUID = 1L;
final static LongDeserializer primitiveInstance = new LongDeserializer(Long.class, Long.valueOf(0L));
final static LongDeserializer wrapperInstance = new LongDeserializer(Long.TYPE, null);
public LongDeserializer(Class<Long> cls, Long nvl)
{
super(cls, nvl);
}
@Override
public Long deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
return _parseLong(jp, ctxt);
}
}
@JacksonStdImpl
public static class FloatDeserializer
extends PrimitiveOrWrapperDeserializer<Float>
{
private static final long serialVersionUID = 1L;
final static FloatDeserializer primitiveInstance = new FloatDeserializer(Float.class, 0.f);
final static FloatDeserializer wrapperInstance = new FloatDeserializer(Float.TYPE, null);
public FloatDeserializer(
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Class<Float> cls, Float nvl)
{
super(cls, nvl);
}
@Override
public Float deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
/* 22-Jan-2009, tatu: Bounds/range checks would be tricky
* here, so let's not bother even trying...
*/
return _parseFloat(jp, ctxt);
}
}
@JacksonStdImpl
public static class DoubleDeserializer
extends PrimitiveOrWrapperDeserializer<Double>
{
private static final long serialVersionUID = 1L;
final static DoubleDeserializer primitiveInstance = new DoubleDeserializer(Double.class, 0.d);
final static DoubleDeserializer wrapperInstance = new DoubleDeserializer(Double.TYPE, null);
public DoubleDeserializer(Class<Double> cls, Double nvl)
{
super(cls, nvl);
}
@Override
public Double deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
return _parseDouble(jp, ctxt);
}
// 1.6: since we can never have type info ("natural type"; String, Boolean, Integer, Double):
// (is it an error to even call this version?)
@Override
public Double deserializeWithType(JsonParser jp, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws IOException, JsonProcessingException
{
return _parseDouble(jp, ctxt);
}
}
/**
* For type <code>Number.class</code>, we can just rely on type
* mappings that plain {@link JsonParser#getNumberValue} returns.
*<p>
* Since 1.5, there is one additional complication: some numeric
* types (specifically, int/Integer and double/Double) are "non-typed";
* meaning that they will NEVER be output with type information.
* But other numeric types may need such type information.
* This is why {@link #deserializeWithType} must be overridden.
*/
@SuppressWarnings("serial")
@JacksonStdImpl
public static class NumberDeserializer
extends StdScalarDeserializer<Number>
{
public final static NumberDeserializer instance = new NumberDeserializer();
public NumberDeserializer() { super(Number.class); }
@Override
public Number deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
if (t == JsonToken.VALUE_NUMBER_INT) {
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS)) {
return jp.getBigIntegerValue();
}
return jp.getNumberValue();
} else if (t == JsonToken.VALUE_NUMBER_FLOAT
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> type);
}
}
return bindings.resolveType(getGenericType());
}
/*
/**********************************************************
/* Partial Annotated impl
/**********************************************************
*/
@Override
public final <A extends Annotation> A getAnnotation(Class<A> acls) {
return _annotations.get(acls);
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
public final AnnotationMap getParameterAnnotations(int index)
{
if (_paramAnnotations != null) {
if (index >= 0 && index < _paramAnnotations.length) {
return _paramAnnotations[index];
}
}
return null;
}
public final AnnotatedParameter getParameter(int index) {
return new AnnotatedParameter(this, getGenericParameterType(index),
getParameterAnnotations(index), index);
}
public abstract int getParameterCount();
public abstract Class<?> getRawParameterType(int index);
public abstract Type getGenericParameterType(int index);
/**
* Method called to fully resolve type of one of parameters, given
* specified type variable bindings.
*/
public final JavaType resolveParameterType(int index, TypeBindings bindings) {
return bindings.resolveType(getGenericParameterType(index));
}
public final int getAnnotationCount() { return _annotations.size(); }
/**
* Method that can be used to (try to) call this object without arguments.
* This may succeed or fail, depending on expected number
* of arguments: caller needs to take care to pass correct number.
* Exceptions are thrown directly from actual low-level call.
*<p>
* Note: only works for constructors and static methods.
*/
public abstract Object call() throws Exception;
/**
* Method that can be used to (try to) call this object with specified arguments.
* This may succeed or fail, depending on expected number
* of arguments: caller needs to take care to pass correct number.
* Exceptions are thrown directly from actual low-level call.
*<p>
* Note: only works for constructors and static methods.
*/
public abstract Object call(Object[] args) throws Exception;
/**
* Method that can be used to (try to) call this object with single arguments.
* This may succeed or fail, depending on expected number
* of arguments: caller needs to take care to pass correct number.
* Exceptions are thrown directly from actual low-level call.
*<p>
* Note: only works for constructors and static methods.
*/
public abstract Object call1(Object arg) throws Exception;
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>AnyGetter();
if (anyGetter != null) {
if (config.canOverrideAccessModifiers()) {
anyGetter.fixAccess();
}
JavaType type = anyGetter.getType(beanDesc.bindingsForBeanType());
// copied from BasicSerializerFactory.buildMapSerializer():
boolean staticTyping = config.isEnabled(MapperFeature.USE_STATIC_TYPING);
JavaType valueType = type.getContentType();
TypeSerializer typeSer = createTypeSerializer(config, valueType);
// last 2 nulls; don't know key, value serializers (yet)
// 23-Feb-2015, tatu: As per [#705], need to support custom serializers
JsonSerializer<?> anySer = findSerializerFromAnnotation(prov, anyGetter);
if (anySer == null) {
// TODO: support '@JsonIgnoreProperties' with any setter?
anySer = MapSerializer.construct(/* ignored props*/ null, type, staticTyping,
typeSer, null, null, /*filterId*/ null);
}
// TODO: can we find full PropertyName?
PropertyName name = new PropertyName(anyGetter.getName());
BeanProperty.Std anyProp = new BeanProperty.Std(name, valueType, null,
beanDesc.getClassAnnotations(), anyGetter, PropertyMetadata.STD_OPTIONAL);
builder.setAnyGetter(new AnyGetterWriter(anyProp, anyGetter, anySer));
}
// Next: need to gather view information, if any:
processViews(config, builder);
// Finally: let interested parties mess with the result bit more...
if (_factoryConfig.hasSerializerModifiers()) {
for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
builder = mod.updateBuilder(config, beanDesc, builder);
}
}
JsonSerializer<Object> ser = (JsonSerializer<Object>) builder.build();
if (ser == null) {
// If we get this far, there were no properties found, so no regular BeanSerializer
// would be constructed. But, couple of exceptions.
// First: if there are known annotations, just create 'empty bean' serializer
if (beanDesc.hasKnownClassAnnotations()) {
return builder.createDummy();
}
}
return ser;
}
protected ObjectIdWriter constructObjectIdHandler(SerializerProvider prov,
BeanDescription beanDesc, List<BeanPropertyWriter> props)
throws JsonMappingException
{
ObjectIdInfo objectIdInfo = beanDesc.getObjectIdInfo();
if (objectIdInfo == null) {
return null;
}
ObjectIdGenerator<?> gen;
Class<?> implClass = objectIdInfo.getGeneratorType();
// Just one special case: Property-based generator is trickier
if (implClass == ObjectIdGenerators.Property
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Generator.class) { // most special one, needs extra work
String propName = objectIdInfo.getPropertyName().getSimpleName();
BeanPropertyWriter idProp = null;
for (int i = 0, len = props.size() ;; ++i) {
if (i == len) {
throw new IllegalArgumentException("Invalid Object Id definition for "+beanDesc.getBeanClass().getName()
+": can not find property with name '"+propName+"'");
}
BeanPropertyWriter prop = props.get(i);
if (propName.equals(prop.getName())) {
idProp = prop;
/* Let's force it to be the first property to output
* (although it may still get rearranged etc)
*/
if (i > 0) {
props.remove(i);
props.add(0, idProp);
}
break;
}
}
JavaType idType = idProp.getType();
gen = new PropertyBasedObjectIdGenerator(objectIdInfo, idProp);
// one more thing: must ensure that ObjectIdWriter does not actually write the value:
return ObjectIdWriter.construct(idType, (PropertyName) null, gen, objectIdInfo.getAlwaysAsId());
}
// other types are simpler
JavaType type = prov.constructType(implClass);
// Could require type to be passed explicitly, but we should be able to find it too:
JavaType idType = prov.getTypeFactory().findTypeParameters(type, ObjectIdGenerator.class)[0];
gen = prov.objectIdGeneratorInstance(beanDesc.getClassInfo(), objectIdInfo);
return ObjectIdWriter.construct(idType, objectIdInfo.getPropertyName(), gen,
objectIdInfo.getAlwaysAsId());
}
/**
* Method called to construct a filtered writer, for given view
* definitions. Default implementation constructs filter that checks
* active view type to views property is to be included in.
*/
protected BeanPropertyWriter constructFilteredBeanWriter(BeanPropertyWriter writer,
Class<?>[] inViews)
{
return FilteredBeanPropertyWriter.constructViewBased(writer, inViews);
}
protected PropertyBuilder constructPropertyBuilder(SerializationConfig config,
BeanDescription beanDesc)
{
return new PropertyBuilder(config, beanDesc);
}
protected BeanSerializerBuilder constructBeanSerializerBuilder(BeanDescription beanDesc) {
return new BeanSerializerBuilder(beanDesc);
}
/*
/**********************************************************
/* Overridable non-public introspection methods
/**********************************************************
*/
/**
* Helper method used to skip processing for types that we know
* can not be (i.e. are never consider to be) beans:
* things like primitives, Arrays, Enums, and proxy types.
*<p>
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
* Note that usually we shouldn't really be getting these sort of
* types anyway; but better safe than sorry.
*/
protected boolean isPotentialBeanType(Class<?> type)
{
return (ClassUtil.canBeABeanType(type) == null) && !ClassUtil.isProxyType(type);
}
/**
* Method used to collect all actual serializable properties.
* Can be overridden to implement custom detection schemes.
*/
protected List<BeanPropertyWriter> findBeanProperties(SerializerProvider prov,
BeanDescription beanDesc, BeanSerializerBuilder builder)
throws JsonMappingException
{
List<BeanPropertyDefinition> properties = beanDesc.findProperties();
final SerializationConfig config = prov.getConfig();
// [JACKSON-429]: ignore specified types
removeIgnorableTypes(config, beanDesc, properties);
// and possibly remove ones without matching mutator...
if (config.isEnabled(MapperFeature.REQUIRE_SETTERS_FOR_GETTERS)) {
removeSetterlessGetters(config, beanDesc, properties);
}
// nothing? can't proceed (caller may or may not throw an exception)
if (properties.isEmpty()) {
return null;
}
// null is for value type serializer, which we don't have access to from here (ditto for bean prop)
boolean staticTyping = usesStaticTyping(config, beanDesc, null);
PropertyBuilder pb = constructPropertyBuilder(config, beanDesc);
ArrayList<BeanPropertyWriter> result = new ArrayList<BeanPropertyWriter>(properties.size());
TypeBindings typeBind = beanDesc.bindingsForBeanType();
for (BeanPropertyDefinition property : properties) {
final AnnotatedMember accessor = property.getAccessor();
// [JACKSON-762]: type id? Requires special handling:
if (property.isTypeId()) {
if (accessor != null) { // only add if we can access... but otherwise?
if (config.canOverrideAccessModifiers()) {
accessor.fixAccess();
}
builder.setTypeId(accessor);
}
continue;
}
// [JACKSON-235]: suppress writing of back references
AnnotationIntrospector.ReferenceProperty refType = property.findReferenceType();
if (refType != null && refType.isBackReference()) {
continue;
}
if (accessor instanceof AnnotatedMethod) {
result.add(_constructWriter(prov, property, typeBind, pb, staticTyping, (AnnotatedMethod) accessor));
} else {
result.add(_constructWriter(prov, property, typeBind, pb, staticTyping, (AnnotatedField) accessor));
}
}
return result;
}
/*
/**********************************************************
/* Overridable non-
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>public methods for manipulating bean properties
/**********************************************************
*/
/**
* Overridable method that can filter out properties. Default implementation
* checks annotations class may have.
*/
protected List<BeanPropertyWriter> filterBeanProperties(SerializationConfig config,
BeanDescription beanDesc, List<BeanPropertyWriter> props)
{
AnnotationIntrospector intr = config.getAnnotationIntrospector();
AnnotatedClass ac = beanDesc.getClassInfo();
String[] ignored = intr.findPropertiesToIgnore(ac);
if (ignored != null && ignored.length > 0) {
HashSet<String> ignoredSet = ArrayBuilders.arrayToSet(ignored);
Iterator<BeanPropertyWriter> it = props.iterator();
while (it.hasNext()) {
if (ignoredSet.contains(it.next().getName())) {
it.remove();
}
}
}
return props;
}
/**
* Method called to handle view information for constructed serializer,
* based on bean property writers.
*<p>
* Note that this method is designed to be overridden by sub-classes
* if they want to provide custom view handling. As such it is not
* considered an internal implementation detail, and will be supported
* as part of API going forward.
*/
protected void processViews(SerializationConfig config, BeanSerializerBuilder builder)
{
// [JACKSON-232]: whether non-annotated fields are included by default or not is configurable
List<BeanPropertyWriter> props = builder.getProperties();
boolean includeByDefault = config.isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION);
final int propCount = props.size();
int viewsFound = 0;
BeanPropertyWriter[] filtered = new BeanPropertyWriter[propCount];
// Simple: view information is stored within individual writers, need to combine:
for (int i = 0; i < propCount; ++i) {
BeanPropertyWriter bpw = props.get(i);
Class<?>[] views = bpw.getViews();
if (views == null) { // no view info? include or exclude by default?
if (includeByDefault) {
filtered[i] = bpw;
}
} else {
++viewsFound;
filtered[i] = constructFilteredBeanWriter(bpw, views);
}
}
// minor optimization: if no view info, include-by-default, can leave out filtering info altogether:
if (includeByDefault && viewsFound == 0) {
return;
}
builder.setFilteredProperties(filtered);
}
/**
* Method that will apply by-type limitations (as per [JACKSON-429]);
* by default this is based on {@link com.fasterxml
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>.jackson.annotation.JsonIgnoreType}
* annotation but can be supplied by module-provided introspectors too.
*/
protected void removeIgnorableTypes(SerializationConfig config, BeanDescription beanDesc,
List<BeanPropertyDefinition> properties)
{
AnnotationIntrospector intr = config.getAnnotationIntrospector();
HashMap<Class<?>,Boolean> ignores = new HashMap<Class<?>,Boolean>();
Iterator<BeanPropertyDefinition> it = properties.iterator();
while (it.hasNext()) {
BeanPropertyDefinition property = it.next();
AnnotatedMember accessor = property.getAccessor();
if (accessor == null) {
it.remove();
continue;
}
Class<?> type = accessor.getRawType();
Boolean result = ignores.get(type);
if (result == null) {
BeanDescription desc = config.introspectClassAnnotations(type);
AnnotatedClass ac = desc.getClassInfo();
result = intr.isIgnorableType(ac);
// default to false, non-ignorable
if (result == null) {
result = Boolean.FALSE;
}
ignores.put(type, result);
}
// lotsa work, and yes, it is ignorable type, so:
if (result.booleanValue()) {
it.remove();
}
}
}
/**
* Helper method that will remove all properties that do not have a mutator.
*/
protected void removeSetterlessGetters(SerializationConfig config, BeanDescription beanDesc,
List<BeanPropertyDefinition> properties)
{
Iterator<BeanPropertyDefinition> it = properties.iterator();
while (it.hasNext()) {
BeanPropertyDefinition property = it.next();
// one caveat: as per [JACKSON-806], only remove implicit properties;
// explicitly annotated ones should remain
if (!property.couldDeserialize() && !property.isExplicitlyIncluded()) {
it.remove();
}
}
}
/*
/**********************************************************
/* Internal helper methods
/**********************************************************
*/
/**
* Secondary helper method for constructing {@link BeanPropertyWriter} for
* given member (field or method).
*/
protected BeanPropertyWriter _constructWriter(SerializerProvider prov,
BeanPropertyDefinition propDef, TypeBindings typeContext,
PropertyBuilder pb, boolean staticTyping, AnnotatedMember accessor)
throws JsonMappingException
{
final PropertyName name = propDef.getFullName();
if (prov.canOverrideAccessModifiers()) {
accessor.fixAccess();
}
JavaType type = accessor.getType(typeContext);
BeanProperty.Std property = new BeanProperty.Std(name, type, propDef.getWrapperName(),
pb.getClassAnnotations(), accessor, propDef.getMetadata());
// Does member specify a
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.cfg;
import java.text.DateFormat;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.Base64Variant;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.introspect.ClassIntrospector;
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
import com.fasterxml.jackson.databind.jsontype.SubtypeResolver;
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
import com.fasterxml.jackson.databind.type.ClassKey;
import com.fasterxml.jackson.databind.type.TypeFactory;
public abstract class MapperConfigBase<CFG extends ConfigFeature,
T extends MapperConfigBase<CFG,T>>
extends MapperConfig<T>
implements java.io.Serializable
{
private static final long serialVersionUID = 6062961959359172474L;
private final static int DEFAULT_MAPPER_FEATURES = collectFeatureDefaults(MapperFeature.class);
/*
/**********************************************************
/* Immutable config
/**********************************************************
*/
/**
* Mix-in annotation mappings to use, if any: immutable,
* can not be changed once defined.
*/
protected final Map<ClassKey,Class<?>> _mixInAnnotations;
/**
* Registered concrete subtypes that can be used instead of (or
* in addition to) ones declared using annotations.
*/
protected final SubtypeResolver _subtypeResolver;
/**
* Explicitly defined root name to use, if any; if empty
* String, will disable root-name wrapping; if null, will
* use defaults
*/
protected final String _rootName;
/**
* View to use for filtering out properties to serialize
* or deserialize.
* Null if none (will also be assigned null if <code>Object.class</code>
* is defined), meaning that all properties are to be included.
*/
protected final Class<?> _view;
/**
* Contextual attributes accessible (get and set) during processing,
* on per-call basis.
*
* @since 2.3
*/
protected final ContextAttributes _attributes;
/*
/**********************************************************
/* Construction
/**********************************************************
*/
/**
* Constructor used when creating a new instance (compared to
* that
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> of creating fluent copies)
*/
protected MapperConfigBase(BaseSettings base,
SubtypeResolver str, Map<ClassKey,Class<?>> mixins)
{
super(base, DEFAULT_MAPPER_FEATURES);
_mixInAnnotations = mixins;
_subtypeResolver = str;
_rootName = null;
_view = null;
// default to "no attributes"
_attributes = ContextAttributes.getEmpty();
}
/**
* Pass-through constructor used when no changes are needed to the
* base class.
*/
protected MapperConfigBase(MapperConfigBase<CFG,T> src)
{
super(src);
_mixInAnnotations = src._mixInAnnotations;
_subtypeResolver = src._subtypeResolver;
_rootName = src._rootName;
_view = src._view;
_attributes = src._attributes;
}
protected MapperConfigBase(MapperConfigBase<CFG,T> src, BaseSettings base)
{
super(base, src._mapperFeatures);
_mixInAnnotations = src._mixInAnnotations;
_subtypeResolver = src._subtypeResolver;
_rootName = src._rootName;
_view = src._view;
_attributes = src._attributes;
}
protected MapperConfigBase(MapperConfigBase<CFG,T> src, int mapperFeatures)
{
super(src._base, mapperFeatures);
_mixInAnnotations = src._mixInAnnotations;
_subtypeResolver = src._subtypeResolver;
_rootName = src._rootName;
_view = src._view;
_attributes = src._attributes;
}
protected MapperConfigBase(MapperConfigBase<CFG,T> src, SubtypeResolver str) {
super(src);
_mixInAnnotations = src._mixInAnnotations;
_subtypeResolver = str;
_rootName = src._rootName;
_view = src._view;
_attributes = src._attributes;
}
protected MapperConfigBase(MapperConfigBase<CFG,T> src, String rootName) {
super(src);
_mixInAnnotations = src._mixInAnnotations;
_subtypeResolver = src._subtypeResolver;
_rootName = rootName;
_view = src._view;
_attributes = src._attributes;
}
protected MapperConfigBase(MapperConfigBase<CFG,T> src, Class<?> view)
{
super(src);
_mixInAnnotations = src._mixInAnnotations;
_subtypeResolver = src._subtypeResolver;
_rootName = src._rootName;
_view = view;
_attributes = src._attributes;
}
/**
* @since 2.1
*/
protected MapperConfigBase(MapperConfigBase<CFG,
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>T> src, Map<ClassKey,Class<?>> mixins)
{
super(src);
_mixInAnnotations = mixins;
_subtypeResolver = src._subtypeResolver;
_rootName = src._rootName;
_view = src._view;
_attributes = src._attributes;
}
/**
* @since 2.3
*/
protected MapperConfigBase(MapperConfigBase<CFG,T> src, ContextAttributes attr)
{
super(src);
_mixInAnnotations = src._mixInAnnotations;
_subtypeResolver = src._subtypeResolver;
_rootName = src._rootName;
_view = src._view;
_attributes = attr;
}
/*
/**********************************************************
/* Addition fluent factory methods, common to all sub-types
/**********************************************************
*/
/**
* Method for constructing and returning a new instance with different
* {@link AnnotationIntrospector} to use (replacing old one).
*<p>
* NOTE: make sure to register new instance with <code>ObjectMapper</code>
* if directly calling this method.
*/
public abstract T with(AnnotationIntrospector ai);
/**
* Method for constructing and returning a new instance with additional
* {@link AnnotationIntrospector} appended (as the lowest priority one)
*/
public abstract T withAppendedAnnotationIntrospector(AnnotationIntrospector introspector);
/**
* Method for constructing and returning a new instance with additional
* {@link AnnotationIntrospector} inserted (as the highest priority one)
*/
public abstract T withInsertedAnnotationIntrospector(AnnotationIntrospector introspector);
/**
* Method for constructing and returning a new instance with different
* {@link ClassIntrospector}
* to use.
*<p>
* NOTE: make sure to register new instance with <code>ObjectMapper</code>
* if directly calling this method.
*/
public abstract T with(ClassIntrospector ci);
/**
* Method for constructing and returning a new instance with different
* {@link DateFormat}
* to use.
*<p>
* NOTE: make sure to register new instance with <code>ObjectMapper</code>
* if directly calling this method.
*/
public abstract T with(DateFormat df);
/**
* Method for constructing and returning a new instance with different
* {@link HandlerInstantiator}
* to use.
*<p>
* NOTE: make sure to register new instance with <code>ObjectMapper</code>
* if directly calling this method.
*/
public abstract T with(HandlerInstantiator hi);
/**
* Method for constructing and returning a new instance with different
* {@link PropertyNamingStrategy}
* to use.
*
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS><p>
* NOTE: make sure to register new instance with <code>ObjectMapper</code>
* if directly calling this method.
*/
public abstract T with(PropertyNamingStrategy strategy);
/**
* Method for constructing and returning a new instance with different
* root name to use (none, if null).
*<p>
* Note that when a root name is set to a non-Empty String, this will automatically force use
* of root element wrapping with given name. If empty String passed, will
* disable root name wrapping; and if null used, will instead use
* <code>SerializationFeature</code> to determine if to use wrapping, and annotation
* (or default name) for actual root name to use.
*
* @param rootName to use: if null, means "use default" (clear setting);
* if empty String ("") means that no root name wrapping is used;
* otherwise defines root name to use.
*/
public abstract T withRootName(String rootName);
/**
* Method for constructing and returning a new instance with different
* {@link SubtypeResolver}
* to use.
*<p>
* NOTE: make sure to register new instance with <code>ObjectMapper</code>
* if directly calling this method.
*/
public abstract T with(SubtypeResolver str);
/**
* Method for constructing and returning a new instance with different
* {@link TypeFactory}
* to use.
*/
public abstract T with(TypeFactory typeFactory);
/**
* Method for constructing and returning a new instance with different
* {@link TypeResolverBuilder} to use.
*/
public abstract T with(TypeResolverBuilder<?> trb);
/**
* Method for constructing and returning a new instance with different
* view to use.
*/
public abstract T withView(Class<?> view);
/**
* Method for constructing and returning a new instance with different
* {@link VisibilityChecker}
* to use.
*/
public abstract T with(VisibilityChecker<?> vc);
/**
* Method for constructing and returning a new instance with different
* minimal visibility level for specified property type
*/
public abstract T withVisibility(PropertyAccessor forMethod, JsonAutoDetect.Visibility visibility);
/**
* Method for constructing and returning a new instance with different
* default {@link java.util.Locale} to use for formatting.
*/
public abstract T with(Locale l);
/**
* Method for constructing and returning a new instance with different
* default {@link java.util.TimeZone} to use for formatting of date values.
*/
public abstract T with(TimeZone tz);
/**
* Method for constructing and returning a new instance with different
* default {@link Base64Variant} to use with base
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>64-encoded binary values.
*/
public abstract T with(Base64Variant base64);
/**
* Method for constructing an instance that has specified
* contextual attributes.
*
* @since 2.3
*/
public abstract T with(ContextAttributes attrs);
/**
* Method for constructing an instance that has only specified
* attributes, removing any attributes that exist before the call.
*
* @since 2.3
*/
public T withAttributes(Map<Object,Object> attributes) {
return with(getAttributes().withSharedAttributes(attributes));
}
/**
* Method for constructing an instance that has specified
* value for attribute for given key.
*
* @since 2.3
*/
public T withAttribute(Object key, Object value) {
return with(getAttributes().withSharedAttribute(key, value));
}
/**
* Method for constructing an instance that has no
* value for attribute for given key.
*
* @since 2.3
*/
public T withoutAttribute(Object key) {
return with(getAttributes().withoutSharedAttribute(key));
}
/*
/**********************************************************
/* Simple accessors
/**********************************************************
*/
/**
* Accessor for object used for finding out all reachable subtypes
* for supertypes; needed when a logical type name is used instead
* of class name (or custom scheme).
*/
@Override
public final SubtypeResolver getSubtypeResolver() {
return _subtypeResolver;
}
public final String getRootName() {
return _rootName;
}
@Override
public final Class<?> getActiveView() {
return _view;
}
@Override
public final ContextAttributes getAttributes() {
return _attributes;
}
/*
/**********************************************************
/* ClassIntrospector.MixInResolver impl:
/**********************************************************
*/
/**
* Method that will check if there are "mix-in" classes (with mix-in
* annotations) for given class
*/
@Override
public final Class<?> findMixInClassFor(Class<?> cls) {
return (_mixInAnnotations == null) ? null : _mixInAnnotations.get(new ClassKey(cls));
}
public final int mixInCount() {
return (_mixInAnnotations == null) ? 0 : _mixInAnnotations.size();
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.*;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.atomic.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonIntegerFormatVisitor;
import com.fasterxml.jackson.databind.ser.BasicSerializerFactory;
/**
* Class that providers access to serializers user for non-structured JDK types that
* are serializer as scalars; some using basic {@link ToStringSerializer},
* others explicit serializers.
*/
@SuppressWarnings("serial")
public class StdJdkSerializers
{
/**
* Method called by {@link BasicSerializerFactory} to access
* all serializers this class provides.
*/
public static Collection<Map.Entry<Class<?>, Object>> all()
{
HashMap<Class<?>,Object> sers = new HashMap<Class<?>,Object>();
// First things that 'toString()' can handle
final ToStringSerializer sls = ToStringSerializer.instance;
sers.put(java.net.URL.class, sls);
sers.put(java.net.URI.class, sls);
sers.put(Currency.class, sls);
sers.put(UUID.class, new UUIDSerializer());
sers.put(java.util.regex.Pattern.class, sls);
sers.put(Locale.class, sls);
// starting with 1.7, use compact String for Locale
sers.put(Locale.class, sls);
// then atomic types
sers.put(AtomicReference.class, AtomicReferenceSerializer.class);
sers.put(AtomicBoolean.class, AtomicBooleanSerializer.class);
sers.put(AtomicInteger.class, AtomicIntegerSerializer.class);
sers.put(AtomicLong.class, AtomicLongSerializer.class);
// then other types that need specialized serializers
sers.put(File.class, FileSerializer.class);
sers.put(Class.class, ClassSerializer.class);
// And then some stranger types... not 100% they are needed but:
sers.put(Void.class, NullSerializer.instance);
sers.put(Void.TYPE, NullSerializer.instance);
return sers.entrySet();
}
/*
/**********************************************************
/* Serializers for atomic types
/**********************************************************
*/
public static class AtomicBooleanSerializer
extends StdScalarSerializer<AtomicBoolean>
{
public AtomicBooleanSerializer() { super(AtomicBoolean
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.introspect;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.util.*;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.introspect.ClassIntrospector.MixInResolver;
import com.fasterxml.jackson.databind.util.Annotations;
import com.fasterxml.jackson.databind.util.ClassUtil;
public final class AnnotatedClass
extends Annotated
{
private final static AnnotationMap[] NO_ANNOTATION_MAPS = new AnnotationMap[0];
/*
/**********************************************************
/* Configuration
/**********************************************************
*/
/**
* Class for which annotations apply, and that owns other
* components (constructors, methods)
*/
final protected Class<?> _class;
/**
* Ordered set of super classes and interfaces of the
* class itself: included in order of precedence
*/
final protected List<Class<?>> _superTypes;
/**
* Filter used to determine which annotations to gather; used
* to optimize things so that unnecessary annotations are
* ignored.
*/
final protected AnnotationIntrospector _annotationIntrospector;
/**
* Object that knows mapping of mix-in classes (ones that contain
* annotations to add) with their target classes (ones that
* get these additional annotations "mixed in").
*/
final protected MixInResolver _mixInResolver;
/**
* Primary mix-in class; one to use for the annotated class
* itself. Can be null.
*/
final protected Class<?> _primaryMixIn;
/*
/**********************************************************
/* Gathered information
/**********************************************************
*/
/**
* Combined list of Jackson annotations that the class has,
* including inheritable ones from super classes and interfaces
*/
protected AnnotationMap _classAnnotations;
/**
* Flag to indicate whether creator information has been resolved
* or not.
*/
protected boolean _creatorsResolved = false;
/**
* Default constructor of the annotated class, if it has one.
*/
protected AnnotatedConstructor _defaultConstructor;
/**
* Single argument constructors the class has, if any.
*/
protected List<AnnotatedConstructor> _constructors;
/**
* Single argument static methods that might be usable
* as factory methods
*/
protected List<AnnotatedMethod> _creatorMethods;
/**
* Member methods of interest; for now ones with 0 or 1 arguments
* (just optimization, since others won't be used now)
*/
protected AnnotatedMethodMap _memberMethods;
/**
* Member fields of interest: ones that are either public,
* or have at least one annotation.
*/
protected List<AnnotatedField
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>> _fields;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
/**
* Constructor will not do any initializations, to allow for
* configuring instances differently depending on use cases
*/
private AnnotatedClass(Class<?> cls, List<Class<?>> superTypes,
AnnotationIntrospector aintr, MixInResolver mir,
AnnotationMap classAnnotations)
{
_class = cls;
_superTypes = superTypes;
_annotationIntrospector = aintr;
_mixInResolver = mir;
_primaryMixIn = (_mixInResolver == null) ? null
: _mixInResolver.findMixInClassFor(_class);
_classAnnotations = classAnnotations;
}
@Override
public AnnotatedClass withAnnotations(AnnotationMap ann) {
return new AnnotatedClass(_class, _superTypes,
_annotationIntrospector, _mixInResolver, ann);
}
/**
* Factory method that instantiates an instance. Returned instance
* will only be initialized with class annotations, but not with
* any method information.
*/
public static AnnotatedClass construct(Class<?> cls,
AnnotationIntrospector aintr, MixInResolver mir)
{
return new AnnotatedClass(cls,
ClassUtil.findSuperTypes(cls, null), aintr, mir, null);
}
/**
* Method similar to {@link #construct}, but that will NOT include
* information from supertypes; only class itself and any direct
* mix-ins it may have.
*/
public static AnnotatedClass constructWithoutSuperTypes(Class<?> cls,
AnnotationIntrospector aintr, MixInResolver mir)
{
return new AnnotatedClass(cls,
Collections.<Class<?>>emptyList(), aintr, mir, null);
}
/*
/**********************************************************
/* Annotated impl
/**********************************************************
*/
@Override
public Class<?> getAnnotated() { return _class; }
@Override
public int getModifiers() { return _class.getModifiers(); }
@Override
public String getName() { return _class.getName(); }
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls)
{
if (_classAnnotations == null) {
resolveClassAnnotations();
}
return _classAnnotations.get(acls);
}
@Override
public Type getGenericType() {
return _class;
}
@Override
public Class<?> getRawType() {
return _class;
}
@Override
public Iterable<Annotation> annotations() {
if (_classAnnotations == null) {
resolveClassAnnotations();
}
return _classAnnotations.annotations();
}
@Override
protected AnnotationMap getAllAnnotations() {
if (_classAnnotations ==
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> null) {
resolveClassAnnotations();
}
return _classAnnotations;
}
/*
/**********************************************************
/* Public API, generic accessors
/**********************************************************
*/
public Annotations getAnnotations() {
if (_classAnnotations == null) {
resolveClassAnnotations();
}
return _classAnnotations;
}
public boolean hasAnnotations() {
if (_classAnnotations == null) {
resolveClassAnnotations();
}
return _classAnnotations.size() > 0;
}
public AnnotatedConstructor getDefaultConstructor()
{
if (!_creatorsResolved) {
resolveCreators();
}
return _defaultConstructor;
}
public List<AnnotatedConstructor> getConstructors()
{
if (!_creatorsResolved) {
resolveCreators();
}
return _constructors;
}
public List<AnnotatedMethod> getStaticMethods()
{
if (!_creatorsResolved) {
resolveCreators();
}
return _creatorMethods;
}
public Iterable<AnnotatedMethod> memberMethods()
{
if (_memberMethods == null) {
resolveMemberMethods();
}
return _memberMethods;
}
public int getMemberMethodCount()
{
if (_memberMethods == null) {
resolveMemberMethods();
}
return _memberMethods.size();
}
public AnnotatedMethod findMethod(String name, Class<?>[] paramTypes)
{
if (_memberMethods == null) {
resolveMemberMethods();
}
return _memberMethods.find(name, paramTypes);
}
public int getFieldCount() {
if (_fields == null) {
resolveFields();
}
return _fields.size();
}
public Iterable<AnnotatedField> fields()
{
if (_fields == null) {
resolveFields();
}
return _fields;
}
/*
/**********************************************************
/* Public API, main-level resolution methods
/**********************************************************
*/
/**
* Initialization method that will recursively collect Jackson
* annotations for this class and all super classes and
* interfaces.
*/
private void resolveClassAnnotations()
{
_classAnnotations = new AnnotationMap();
// [JACKSON-659] Should skip processing if annotation processing disabled
if (_annotationIntrospector != null) {
// add mix-in annotations first (overrides)
if (_primaryMixIn != null) {
_addClassMixIns(_classAnnotations, _class, _primaryMixIn);
}
// first, annotations from the class itself:
_addAnnotationsIfNotPresent(_classAnnotations, _class.getDeclaredAnnotations());
// and then from super types
for (Class<?> cls : _superTypes) {
// and mix mix-in annotations in-between
_addClassMixIns(_classAnnotations, cls);
_addAnnotations
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> as per [JACKSON-850]
//int argCount = m.getParameterTypes().length;
if (creatorMethods == null) {
creatorMethods = new ArrayList<AnnotatedMethod>(8);
}
creatorMethods.add(_constructCreatorMethod(m));
}
if (creatorMethods == null) {
_creatorMethods = Collections.emptyList();
} else {
_creatorMethods = creatorMethods;
// mix-ins to mix in?
if (_primaryMixIn != null) {
_addFactoryMixIns(_primaryMixIn);
}
// anything to ignore at this point?
if (_annotationIntrospector != null) {
// count down to allow safe removal
for (int i = _creatorMethods.size(); --i >= 0; ) {
if (_annotationIntrospector.hasIgnoreMarker(_creatorMethods.get(i))) {
_creatorMethods.remove(i);
}
}
}
}
_creatorsResolved = true;
}
/**
* Method for resolving member method information: aggregating all non-static methods
* and combining annotations (to implement method-annotation inheritance)
*
* @param methodFilter Filter used to determine which methods to include
*/
private void resolveMemberMethods()
{
_memberMethods = new AnnotatedMethodMap();
AnnotatedMethodMap mixins = new AnnotatedMethodMap();
// first: methods from the class itself
_addMemberMethods(_class, _memberMethods, _primaryMixIn, mixins);
// and then augment these with annotations from super-types:
for (Class<?> cls : _superTypes) {
Class<?> mixin = (_mixInResolver == null) ? null : _mixInResolver.findMixInClassFor(cls);
_addMemberMethods(cls, _memberMethods, mixin, mixins);
}
// Special case: mix-ins for Object.class? (to apply to ALL classes)
if (_mixInResolver != null) {
Class<?> mixin = _mixInResolver.findMixInClassFor(Object.class);
if (mixin != null) {
_addMethodMixIns(_class, _memberMethods, mixin, mixins);
}
}
/* Any unmatched mix-ins? Most likely error cases (not matching
* any method); but there is one possible real use case:
* exposing Object#hashCode (alas, Object#getClass can NOT be
* exposed, see [JACKSON-140])
*/
// 14-Feb-2011, tatu: AnnotationIntrospector is null if annotations not enabled; if so, can skip:
if (_annotationIntrospector != null) {
if (!mixins.isEmpty()) {
Iterator<AnnotatedMethod> it =
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> mixins.iterator();
while (it.hasNext()) {
AnnotatedMethod mixIn = it.next();
try {
Method m = Object.class.getDeclaredMethod(mixIn.getName(), mixIn.getRawParameterTypes());
if (m != null) {
AnnotatedMethod am = _constructMethod(m);
_addMixOvers(mixIn.getAnnotated(), am, false);
_memberMethods.add(am);
}
} catch (Exception e) { }
}
}
}
}
/**
* Method that will collect all member (non-static) fields
* that are either public, or have at least a single annotation
* associated with them.
*/
private void resolveFields()
{
Map<String,AnnotatedField> foundFields = _findFields(_class, null);
if (foundFields == null || foundFields.size() == 0) {
_fields = Collections.emptyList();
} else {
_fields = new ArrayList<AnnotatedField>(foundFields.size());
_fields.addAll(foundFields.values());
}
}
/*
/**********************************************************
/* Helper methods for resolving class annotations
/* (resolution consisting of inheritance, overrides,
/* and injection of mix-ins as necessary)
/**********************************************************
*/
/**
* Helper method for adding any mix-in annotations specified
* class might have.
*/
protected void _addClassMixIns(AnnotationMap annotations, Class<?> toMask)
{
if (_mixInResolver != null) {
_addClassMixIns(annotations, toMask, _mixInResolver.findMixInClassFor(toMask));
}
}
protected void _addClassMixIns(AnnotationMap annotations, Class<?> toMask,
Class<?> mixin)
{
if (mixin == null) {
return;
}
// Ok, first: annotations from mix-in class itself:
_addAnnotationsIfNotPresent(annotations, mixin.getDeclaredAnnotations());
/* And then from its supertypes, if any. But note that we will
* only consider super-types up until reaching the masked
* class (if found); this because often mix-in class
* is a sub-class (for convenience reasons). And if so, we
* absolutely must NOT include super types of masked class,
* as that would inverse precedence of annotations.
*/
for (Class<?> parent : ClassUtil.findSuperTypes(mixin, toMask)) {
_addAnnotationsIfNotPresent(annotations, parent.getDeclaredAnnotations());
}
}
/*
/**********************************************************
/* Helper methods for populating creator (ctor, factory) information
/**********************************************************
*/
protected void _addConstructorMixIns(Class<?> mixin)
{
MemberKey[] ctorKeys = null;
int
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> ctorCount = (_constructors == null) ? 0 : _constructors.size();
for (Constructor<?> ctor : mixin.getDeclaredConstructors()) {
if (ctor.getParameterTypes().length == 0) {
if (_defaultConstructor != null) {
_addMixOvers(ctor, _defaultConstructor, false);
}
} else {
if (ctorKeys == null) {
ctorKeys = new MemberKey[ctorCount];
for (int i = 0; i < ctorCount; ++i) {
ctorKeys[i] = new MemberKey(_constructors.get(i).getAnnotated());
}
}
MemberKey key = new MemberKey(ctor);
for (int i = 0; i < ctorCount; ++i) {
if (!key.equals(ctorKeys[i])) {
continue;
}
_addMixOvers(ctor, _constructors.get(i), true);
break;
}
}
}
}
protected void _addFactoryMixIns(Class<?> mixin)
{
MemberKey[] methodKeys = null;
int methodCount = _creatorMethods.size();
for (Method m : mixin.getDeclaredMethods()) {
if (!Modifier.isStatic(m.getModifiers())) {
continue;
}
if (m.getParameterTypes().length == 0) {
continue;
}
if (methodKeys == null) {
methodKeys = new MemberKey[methodCount];
for (int i = 0; i < methodCount; ++i) {
methodKeys[i] = new MemberKey(_creatorMethods.get(i).getAnnotated());
}
}
MemberKey key = new MemberKey(m);
for (int i = 0; i < methodCount; ++i) {
if (!key.equals(methodKeys[i])) {
continue;
}
_addMixOvers(m, _creatorMethods.get(i), true);
break;
}
}
}
/*
/**********************************************************
/* Helper methods for populating method information
/**********************************************************
*/
protected void _addMemberMethods(Class<?> cls, AnnotatedMethodMap methods,
Class<?> mixInCls, AnnotatedMethodMap mixIns)
{
// first, mixIns, since they have higher priority then class methods
if (mixInCls != null) {
_addMethodMixIns(cls, methods, mixInCls, mixIns);
}
if (cls == null) { // just so caller need not check when passing super-class
return;
}
// then methods from the class itself
for (Method m : cls.getDeclaredMethods()) {
if (!_isIncludableMemberMethod(m)) {
continue;
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
}
AnnotatedMethod old = methods.find(m);
if (old == null) {
AnnotatedMethod newM = _constructMethod(m);
methods.add(newM);
// Ok, but is there a mix-in to connect now?
old = mixIns.remove(m);
if (old != null) {
_addMixOvers(old.getAnnotated(), newM, false);
}
} else {
/* If sub-class already has the method, we only want to augment
* annotations with entries that are not masked by sub-class.
*/
_addMixUnders(m, old);
/* 06-Jan-2010, tatu: [JACKSON-450] Except that if method we saw first is
* from an interface, and we now find a non-interface definition, we should
* use this method, but with combination of annotations.
* This helps (or rather, is essential) with JAXB annotations and
* may also result in faster method calls (interface calls are slightly
* costlier than regular method calls)
*/
if (old.getDeclaringClass().isInterface() && !m.getDeclaringClass().isInterface()) {
methods.add(old.withMethod(m));
}
}
}
}
protected void _addMethodMixIns(Class<?> targetClass, AnnotatedMethodMap methods,
Class<?> mixInCls, AnnotatedMethodMap mixIns)
{
List<Class<?>> parents = new ArrayList<Class<?>>();
parents.add(mixInCls);
ClassUtil.findSuperTypes(mixInCls, targetClass, parents);
for (Class<?> mixin : parents) {
for (Method m : mixin.getDeclaredMethods()) {
if (!_isIncludableMemberMethod(m)) {
continue;
}
AnnotatedMethod am = methods.find(m);
/* Do we already have a method to augment (from sub-class
* that will mask this mixIn)? If so, add if visible
* without masking (no such annotation)
*/
if (am != null) {
_addMixUnders(m, am);
/* Otherwise will have precedence, but must wait
* until we find the real method (mixIn methods are
* just placeholder, can't be called)
*/
} else {
// Well, or, as per [Issue#515], multi-level merge within mixins...
am = mixIns.find(m);
if (am != null) {
_addMixUnders(m, am);
} else {
mixIns.add(_constructMethod(m));
}
}
}
}
}
/*
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
/**********************************************************
/* Helper methods for populating field information
/**********************************************************
*/
protected Map<String,AnnotatedField> _findFields(Class<?> c, Map<String,AnnotatedField> fields)
{
/* First, a quick test: we only care for regular classes (not
* interfaces, primitive types etc), except for Object.class.
* A simple check to rule out other cases is to see if there
* is a super class or not.
*/
Class<?> parent = c.getSuperclass();
if (parent != null) {
// Let's add super-class' fields first, then ours.
/* 21-Feb-2010, tatu: Need to handle masking: as per [JACKSON-226]
* we otherwise get into trouble...
*/
fields = _findFields(parent, fields);
for (Field f : c.getDeclaredFields()) {
// static fields not included, nor transient
if (!_isIncludableField(f)) {
continue;
}
/* Ok now: we can (and need) not filter out ignorable fields
* at this point; partly because mix-ins haven't been
* added, and partly because logic can be done when
* determining get/settability of the field.
*/
if (fields == null) {
fields = new LinkedHashMap<String,AnnotatedField>();
}
fields.put(f.getName(), _constructField(f));
}
// And then... any mix-in overrides?
if (_mixInResolver != null) {
Class<?> mixin = _mixInResolver.findMixInClassFor(c);
if (mixin != null) {
_addFieldMixIns(parent, mixin, fields);
}
}
}
return fields;
}
/**
* Method called to add field mix-ins from given mix-in class (and its fields)
* into already collected actual fields (from introspected classes and their
* super-classes)
*/
protected void _addFieldMixIns(Class<?> targetClass, Class<?> mixInCls,
Map<String,AnnotatedField> fields)
{
List<Class<?>> parents = new ArrayList<Class<?>>();
parents.add(mixInCls);
ClassUtil.findSuperTypes(mixInCls, targetClass, parents);
for (Class<?> mixin : parents) {
for (Field mixinField : mixin.getDeclaredFields()) {
// there are some dummy things (static, synthetic); better ignore
if (!_isIncludableField(mixinField)) {
continue;
}
String name = mixinField.getName();
// anything to mask? (if not, quietly ignore)
AnnotatedField maskedField = fields
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>.get(name);
if (maskedField != null) {
_addOrOverrideAnnotations(maskedField, mixinField.getDeclaredAnnotations());
}
}
}
}
/*
/**********************************************************
/* Helper methods, constructing value types
/**********************************************************
*/
protected AnnotatedMethod _constructMethod(Method m)
{
/* note: parameter annotations not used for regular (getter, setter)
* methods; only for creator methods (static factory methods)
* -- at least not yet!
*/
if (_annotationIntrospector == null) { // when annotation processing is disabled
return new AnnotatedMethod(this, m, _emptyAnnotationMap(), null);
}
return new AnnotatedMethod(this, m, _collectRelevantAnnotations(m.getDeclaredAnnotations()), null);
}
protected AnnotatedConstructor _constructConstructor(Constructor<?> ctor, boolean defaultCtor)
{
if (_annotationIntrospector == null) { // when annotation processing is disabled
return new AnnotatedConstructor(this, ctor, _emptyAnnotationMap(), _emptyAnnotationMaps(ctor.getParameterTypes().length));
}
if (defaultCtor) {
return new AnnotatedConstructor(this, ctor, _collectRelevantAnnotations(ctor.getDeclaredAnnotations()), null);
}
Annotation[][] paramAnns = ctor.getParameterAnnotations();
int paramCount = ctor.getParameterTypes().length;
/* [JACKSON-701]: Looks like JDK has discrepancy, whereas annotations for implicit 'this'
* (for non-static inner classes) are NOT included, but type is? Strange, sounds like
* a bug. Alas, we can't really fix that...
*/
// Also: [JACKSON-757] (enum value constructors)
AnnotationMap[] resolvedAnnotations = null;
if (paramCount != paramAnns.length) {
// Limits of the work-around (to avoid hiding real errors):
// first, only applicable for member classes and then either:
Class<?> dc = ctor.getDeclaringClass();
// (a) is enum, which have two extra hidden params (name, index)
if (dc.isEnum() && (paramCount == paramAnns.length + 2)) {
Annotation[][] old = paramAnns;
paramAnns = new Annotation[old.length+2][];
System.arraycopy(old, 0, paramAnns, 2, old.length);
resolvedAnnotations = _collectRelevantAnnotations(paramAnns);
} else if (dc.isMemberClass()) {
// (b) non-static inner classes, get implicit 'this' for parameter, not annotation
if (paramCount == (paramAnns.length + 1)) {
// hack attack:
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> != null) || (_setters != null) || (_fields != null);
}
@Override
public boolean couldSerialize() {
return (_getters != null) || (_fields != null);
}
@Override
public AnnotatedMethod getGetter()
{
// Easy with zero or one getters...
Linked<AnnotatedMethod> curr = _getters;
if (curr == null) {
return null;
}
Linked<AnnotatedMethod> next = curr.next;
if (next == null) {
return curr.value;
}
// But if multiple, verify that they do not conflict...
for (; next != null; next = next.next) {
/* [JACKSON-255] Allow masking, i.e. do not report exception if one
* is in super-class from the other
*/
Class<?> currClass = curr.value.getDeclaringClass();
Class<?> nextClass = next.value.getDeclaringClass();
if (currClass != nextClass) {
if (currClass.isAssignableFrom(nextClass)) { // next is more specific
curr = next;
continue;
}
if (nextClass.isAssignableFrom(currClass)) { // current more specific
continue;
}
}
/* 30-May-2014, tatu: Three levels of precedence:
*
* 1. Regular getters ("getX")
* 2. Is-getters ("isX")
* 3. Implicit, possible getters ("x")
*/
int priNext = _getterPriority(next.value);
int priCurr = _getterPriority(curr.value);
if (priNext != priCurr) {
if (priNext < priCurr) {
curr = next;
}
continue;
}
throw new IllegalArgumentException("Conflicting getter definitions for property \""+getName()+"\": "
+curr.value.getFullName()+" vs "+next.value.getFullName());
}
// One more thing; to avoid having to do it again...
_getters = curr.withoutNext();
return curr.value;
}
@Override
public AnnotatedMethod getSetter()
{
// Easy with zero or one getters...
Linked<AnnotatedMethod> curr = _setters;
if (curr == null) {
return null;
}
Linked<AnnotatedMethod> next = curr.next;
if (next == null) {
return curr.value;
}
// But if multiple, verify that they do not conflict...
for (; next != null; next = next.next) {
/* [JACKSON-255] Allow masking, i.e. do not report exception if one
* is in super-class from the
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> other
*/
Class<?> currClass = curr.value.getDeclaringClass();
Class<?> nextClass = next.value.getDeclaringClass();
if (currClass != nextClass) {
if (currClass.isAssignableFrom(nextClass)) { // next is more specific
curr = next;
continue;
}
if (nextClass.isAssignableFrom(currClass)) { // current more specific
continue;
}
}
/* 30-May-2014, tatu: Two levels of precedence:
*
* 1. Regular setters ("setX(...)")
* 2. Implicit, possible setters ("x(...)")
*/
int priNext = _setterPriority(next.value);
int priCurr = _setterPriority(curr.value);
if (priNext != priCurr) {
if (priNext < priCurr) {
curr = next;
}
continue;
}
throw new IllegalArgumentException("Conflicting setter definitions for property \""+getName()+"\": "
+curr.value.getFullName()+" vs "+next.value.getFullName());
}
// One more thing; to avoid having to do it again...
_setters = curr.withoutNext();
return curr.value;
}
@Override
public AnnotatedField getField()
{
if (_fields == null) {
return null;
}
// If multiple, verify that they do not conflict...
AnnotatedField field = _fields.value;
Linked<AnnotatedField> next = _fields.next;
for (; next != null; next = next.next) {
AnnotatedField nextField = next.value;
Class<?> fieldClass = field.getDeclaringClass();
Class<?> nextClass = nextField.getDeclaringClass();
if (fieldClass != nextClass) {
if (fieldClass.isAssignableFrom(nextClass)) { // next is more specific
field = nextField;
continue;
}
if (nextClass.isAssignableFrom(fieldClass)) { // getter more specific
continue;
}
}
throw new IllegalArgumentException("Multiple fields representing property \""+getName()+"\": "
+field.getFullName()+" vs "+nextField.getFullName());
}
return field;
}
@Override
public AnnotatedParameter getConstructorParameter()
{
if (_ctorParameters == null) {
return null;
}
/* Hmmh. Checking for constructor parameters is trickier; for one,
* we must allow creator and factory method annotations.
* If this is the case, constructor parameter has the precedence.
*
* So, for now, just try finding the first constructor parameter;
* if none, first factory method. And don't check for dups, if we must,
* can start checking for
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> them later on.
*/
Linked<AnnotatedParameter> curr = _ctorParameters;
do {
if (curr.value.getOwner() instanceof AnnotatedConstructor) {
return curr.value;
}
curr = curr.next;
} while (curr != null);
return _ctorParameters.value;
}
@Override
public Iterator<AnnotatedParameter> getConstructorParameters() {
if (_ctorParameters == null) {
return EmptyIterator.instance();
}
return new MemberIterator<AnnotatedParameter>(_ctorParameters);
}
@Override
public AnnotatedMember getAccessor()
{
AnnotatedMember m = getGetter();
if (m == null) {
m = getField();
}
return m;
}
@Override
public AnnotatedMember getMutator()
{
AnnotatedMember m = getConstructorParameter();
if (m == null) {
m = getSetter();
if (m == null) {
m = getField();
}
}
return m;
}
@Override
public AnnotatedMember getNonConstructorMutator() {
AnnotatedMember m = getSetter();
if (m == null) {
m = getField();
}
return m;
}
@Override
public AnnotatedMember getPrimaryMember() {
if (_forSerialization) {
return getAccessor();
}
return getMutator();
}
protected int _getterPriority(AnnotatedMethod m)
{
final String name = m.getName();
// [#238]: Also, regular getters have precedence over "is-getters"
if (name.startsWith("get") && name.length() > 3) {
// should we check capitalization?
return 1;
}
if (name.startsWith("is") && name.length() > 2) {
return 2;
}
return 3;
}
protected int _setterPriority(AnnotatedMethod m)
{
final String name = m.getName();
if (name.startsWith("set") && name.length() > 3) {
// should we check capitalization?
return 1;
}
return 2;
}
/*
/**********************************************************
/* Implementations of refinement accessors
/**********************************************************
*/
@Override
public Class<?>[] findViews() {
return fromMemberAnnotations(new WithMember<Class<?>[]>() {
@Override
public Class<?>[] withMember(AnnotatedMember member) {
return _annotationIntrospector.findViews(member);
}
});
}
@Override
public AnnotationIntrospector.ReferenceProperty findReferenceType() {
return fromMemberAnnotations(new WithMember<AnnotationIntrospector.ReferenceProperty>() {
@Override
public AnnotationIntros
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> "+propCount+" properties (in JSON Array)");
}
// otherwise, skip until end
while (p.nextToken() != JsonToken.END_ARRAY) {
p.skipChildren();
}
return bean;
}
// needed since 2.1
@Override
public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt)
throws IOException
{
return _deserializeFromNonArray(p, ctxt);
}
/*
/**********************************************************
/* Helper methods, non-standard creation
/**********************************************************
*/
/**
* Alternate deserialization method that has to check many more configuration
* aspects than the "vanilla" processing.
*/
protected Object _deserializeNonVanilla(JsonParser p, DeserializationContext ctxt)
throws IOException
{
if (_nonStandardCreation) {
return _deserializeWithCreator(p, ctxt);
}
final Object bean = _valueInstantiator.createUsingDefault(ctxt);
// [databind#631]: Assign current value, to be accessible by custom serializers
p.setCurrentValue(bean);
if (_injectables != null) {
injectValues(ctxt, bean);
}
Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
final SettableBeanProperty[] props = _orderedProperties;
int i = 0;
final int propCount = props.length;
while (true) {
if (p.nextToken() == JsonToken.END_ARRAY) {
return bean;
}
if (i == propCount) {
break;
}
SettableBeanProperty prop = props[i];
++i;
if (prop != null) { // normal case
if (activeView == null || prop.visibleInView(activeView)) {
try {
prop.deserializeAndSet(p, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, prop.getName(), ctxt);
}
continue;
}
}
// otherwise, skip it (view-filtered, no prop etc)
p.skipChildren();
}
// Ok; extra fields? Let's fail, unless ignoring extra props is fine
if (!_ignoreAllUnknown) {
throw ctxt.mappingException("Unexpected JSON values; expected at most "+propCount+" properties (in JSON Array)");
}
// otherwise, skip until end
while (p.nextToken() != JsonToken.END_ARRAY) {
p.skipChildren();
}
return bean;
}
protected Object _deserializeWithCreator(JsonParser p, DeserializationContext ctxt)
throws IOException
{
if (_delegateDeserializer != null) {
return _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(p, ctxt));
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>_EMPTY)) {
return MARKER_FOR_EMPTY;
}
return null;
}
/*
/**********************************************************
/* Standard accessor overrides
/**********************************************************
*/
@Override
public boolean isVirtual() { return true; }
@Override
public Class<?> getPropertyType() {
return _declaredType.getRawClass();
}
@Override
public Type getGenericPropertyType() {
return getPropertyType();
}
/*
/**********************************************************
/* Abstract methods for sub-classes to define
/**********************************************************
*/
/**
* Method called to figure out the value to serialize. For simple sub-types
* (such as {@link com.fasterxml.jackson.databind.ser.impl.AttributePropertyWriter})
* this may be one of few methods to define, although more advanced implementations
* may choose to not even use this method (by overriding {@link #serializeAsField})
* and define a bogus implementation.
*/
protected abstract Object value(Object bean, JsonGenerator jgen, SerializerProvider prov) throws Exception;
/**
* Contextualization method called on a newly constructed virtual bean property.
* Usually a new intance needs to be created due to finality of some of configuration
* members; otherwise while recommended, creating a new instance is not strictly-speaking
* mandatory because calls are made in thread-safe manner, as part of initialization
* before use.
*
* @param config Currenct configuration; guaranteed to be {@link SerializationConfig}
* (just not typed since caller does not have dependency to serialization-specific types)
* @param declaringClass Class that contains this property writer
* @param propDef Nominal property definition to use
* @param type Declared type for the property
*/
public abstract VirtualBeanPropertyWriter withConfig(MapperConfig<?> config,
AnnotatedClass declaringClass, BeanPropertyDefinition propDef, JavaType type);
/*
/**********************************************************
/* PropertyWriter serialization method overrides
/**********************************************************
*/
@Override
public void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
{
// NOTE: mostly copied from base class, but off-lined get() access
final Object value = value(bean, gen, prov);
if (value == null) {
if (_nullSerializer != null) {
gen.writeFieldName(_name);
_nullSerializer.serialize(null, gen, prov);
}
return;
}
JsonSerializer<Object> ser = _serializer;
if (ser == null) {
Class<?> cls = value.getClass();
PropertySerializerMap m = _dynamicSerializers;
ser = m.serializerFor(cls);
if (ser == null) {
ser = _findAndAddDynamic(m, cls, prov);
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
}
if (_suppressableValue != null) {
if (MARKER_FOR_EMPTY == _suppressableValue) {
if (ser.isEmpty(prov, value)) {
return;
}
} else if (_suppressableValue.equals(value)) {
return;
}
}
if (value == bean) { // simple check for direct cycles
// three choices: exception; handled by call; or pass-through
if (_handleSelfReference(bean, gen, prov, ser)) {
return;
}
}
gen.writeFieldName(_name);
if (_typeSerializer == null) {
ser.serialize(value, gen, prov);
} else {
ser.serializeWithType(value, gen, prov, _typeSerializer);
}
}
// This one's fine as-is from base class
//public void serializeAsOmittedField(Object bean, JsonGenerator jgen, SerializerProvider prov) throws Exception
@Override
public void serializeAsElement(Object bean, JsonGenerator gen, SerializerProvider prov)
throws Exception
{
// NOTE: mostly copied from base class, but off-lined get() access
final Object value = value(bean, gen, prov);
if (value == null) {
if (_nullSerializer != null) {
_nullSerializer.serialize(null, gen, prov);
} else {
gen.writeNull();
}
return;
}
JsonSerializer<Object> ser = _serializer;
if (ser == null) {
Class<?> cls = value.getClass();
PropertySerializerMap map = _dynamicSerializers;
ser = map.serializerFor(cls);
if (ser == null) {
ser = _findAndAddDynamic(map, cls, prov);
}
}
if (_suppressableValue != null) {
if (MARKER_FOR_EMPTY == _suppressableValue) {
if (ser.isEmpty(prov, value)) {
serializeAsPlaceholder(bean, gen, prov);
return;
}
} else if (_suppressableValue.equals(value)) {
serializeAsPlaceholder(bean, gen, prov);
return;
}
}
if (value == bean) {
if (_handleSelfReference(bean, gen, prov, ser)) {
return;
}
}
if (_typeSerializer == null) {
ser.serialize(value, gen, prov);
} else {
ser.serializeWithType(value, gen, prov, _typeSerializer);
}
}
// This one's fine as-is from base class
//public void serializeAsPlaceholder(Object bean, JsonGenerator jgen, SerializerProvider prov)
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
import java.lang.reflect.Type;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
/**
* Also: default bean access will not do much good with Class.class. But
* we can just serialize the class name and that should be enough.
*/
@SuppressWarnings("serial")
public class ClassSerializer
extends StdScalarSerializer<Class<?>>
{
public ClassSerializer() { super(Class.class, false); }
@Override
public void serialize(Class<?> value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
{
jgen.writeString(value.getName());
}
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint)
{
return createSchemaNode("string", true);
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
throws JsonMappingException
{
visitor.expectStringFormat(typeHint);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URL;
import java.util.Calendar;
import java.util.Currency;
import java.util.Date;
import java.util.Locale;
import java.util.UUID;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.io.NumberInput;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.EnumResolver;
/**
* Default {@link KeyDeserializer} implementation used for most {@link java.util.Map}
* types Jackson supports.
* Implemented as "chameleon" (or swiss pocket knife) class; not particularly elegant,
* but helps reduce number of classes and jar size (class metadata adds significant
* per-class overhead; much more than bytecode).
*/
@JacksonStdImpl
public class StdKeyDeserializer extends KeyDeserializer
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
public final static int TYPE_BOOLEAN = 1;
public final static int TYPE_BYTE = 2;
public final static int TYPE_SHORT = 3;
public final static int TYPE_CHAR = 4;
public final static int TYPE_INT = 5;
public final static int TYPE_LONG = 6;
public final static int TYPE_FLOAT = 7;
public final static int TYPE_DOUBLE = 8;
public final static int TYPE_LOCALE = 9;
public final static int TYPE_DATE = 10;
public final static int TYPE_CALENDAR = 11;
public final static int TYPE_UUID = 12;
public final static int TYPE_URI = 13;
public final static int TYPE_URL = 14;
public final static int TYPE_CLASS = 15;
public final static int TYPE_CURRENCY = 16;
final protected int _kind;
final protected Class<?> _keyClass;
/**
* Some types that are deserialized using a helper deserializer.
*/
protected final FromStringDeserializer<?> _deser;
protected StdKeyDeserializer(int kind, Class<?> cls) {
this(kind, cls, null);
}
protected StdKeyDeserializer(int kind,
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> Class<?> cls, FromStringDeserializer<?> deser) {
_kind = kind;
_keyClass = cls;
_deser = deser;
}
public static StdKeyDeserializer forType(Class<?> raw)
{
int kind;
// first common types:
if (raw == String.class || raw == Object.class) {
return StringKD.forType(raw);
} else if (raw == UUID.class) {
kind = TYPE_UUID;
} else if (raw == Integer.class) {
kind = TYPE_INT;
} else if (raw == Long.class) {
kind = TYPE_LONG;
} else if (raw == Date.class) {
kind = TYPE_DATE;
} else if (raw == Calendar.class) {
kind = TYPE_CALENDAR;
// then less common ones...
} else if (raw == Boolean.class) {
kind = TYPE_BOOLEAN;
} else if (raw == Byte.class) {
kind = TYPE_BYTE;
} else if (raw == Character.class) {
kind = TYPE_CHAR;
} else if (raw == Short.class) {
kind = TYPE_SHORT;
} else if (raw == Float.class) {
kind = TYPE_FLOAT;
} else if (raw == Double.class) {
kind = TYPE_DOUBLE;
} else if (raw == URI.class) {
kind = TYPE_URI;
} else if (raw == URL.class) {
kind = TYPE_URL;
} else if (raw == Class.class) {
kind = TYPE_CLASS;
} else if (raw == Locale.class) {
FromStringDeserializer<?> deser = FromStringDeserializer.findDeserializer(Locale.class);
return new StdKeyDeserializer(TYPE_LOCALE, raw, deser);
} else if (raw == Currency.class) {
FromStringDeserializer<?> deser = FromStringDeserializer.findDeserializer(Currency.class);
return new StdKeyDeserializer(TYPE_CURRENCY, raw, deser);
} else {
return null;
}
return new StdKeyDeserializer(kind, raw);
}
@Override
public Object deserializeKey(String key, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
if (key == null) { // is this even legal call?
return null;
}
try {
Object result = _parse(key, ctxt);
if (result != null) {
return result;
}
} catch (Exception re) {
throw ctxt.weirdKeyException(_keyClass, key, "not a valid representation: "+re.getMessage());
}
if (_keyClass.isEnum() && ctxt.getConfig().isEnabled(
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) {
return null;
}
throw ctxt.weirdKeyException(_keyClass, key, "not a valid representation");
}
public Class<?> getKeyClass() { return _keyClass; }
protected Object _parse(String key, DeserializationContext ctxt) throws Exception
{
switch (_kind) {
case TYPE_BOOLEAN:
if ("true".equals(key)) {
return Boolean.TRUE;
}
if ("false".equals(key)) {
return Boolean.FALSE;
}
throw ctxt.weirdKeyException(_keyClass, key, "value not 'true' or 'false'");
case TYPE_BYTE:
{
int value = _parseInt(key);
// as per [JACKSON-804], allow range up to 255, inclusive
if (value < Byte.MIN_VALUE || value > 255) {
throw ctxt.weirdKeyException(_keyClass, key, "overflow, value can not be represented as 8-bit value");
}
return Byte.valueOf((byte) value);
}
case TYPE_SHORT:
{
int value = _parseInt(key);
if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
throw ctxt.weirdKeyException(_keyClass, key, "overflow, value can not be represented as 16-bit value");
}
return Short.valueOf((short) value);
}
case TYPE_CHAR:
if (key.length() == 1) {
return Character.valueOf(key.charAt(0));
}
throw ctxt.weirdKeyException(_keyClass, key, "can only convert 1-character Strings");
case TYPE_INT:
return _parseInt(key);
case TYPE_LONG:
return _parseLong(key);
case TYPE_FLOAT:
// Bounds/range checks would be tricky here, so let's not bother even trying...
return Float.valueOf((float) _parseDouble(key));
case TYPE_DOUBLE:
return _parseDouble(key);
case TYPE_LOCALE:
try {
return _deser._deserialize(key, ctxt);
} catch (IOException e) {
throw ctxt.weirdKeyException(_keyClass, key, "unable to parse key as locale");
}
case TYPE_CURRENCY:
try {
return _deser._deserialize(key, ctxt);
} catch (IOException e) {
throw ctxt.weirdKeyException(_keyClass, key, "unable to parse key as currency");
}
case TYPE_DATE:
return ctxt.parseDate(key);
case TYPE_CALENDAR:
java.util
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>.Date date = ctxt.parseDate(key);
return (date == null) ? null : ctxt.constructCalendar(date);
case TYPE_UUID:
return UUID.fromString(key);
case TYPE_URI:
return URI.create(key);
case TYPE_URL:
return new URL(key);
case TYPE_CLASS:
try {
return ctxt.findClass(key);
} catch (Exception e) {
throw ctxt.weirdKeyException(_keyClass, key, "unable to parse key as Class");
}
}
return null;
}
/*
/**********************************************************
/* Helper methods for sub-classes
/**********************************************************
*/
protected int _parseInt(String key) throws IllegalArgumentException {
return Integer.parseInt(key);
}
protected long _parseLong(String key) throws IllegalArgumentException {
return Long.parseLong(key);
}
protected double _parseDouble(String key) throws IllegalArgumentException {
return NumberInput.parseDouble(key);
}
/*
/**********************************************************
/* First: the standard "String as String" deserializer
/**********************************************************
*/
@JacksonStdImpl
final static class StringKD extends StdKeyDeserializer
{
private static final long serialVersionUID = 1L;
private final static StringKD sString = new StringKD(String.class);
private final static StringKD sObject = new StringKD(Object.class);
private StringKD(Class<?> nominalType) { super(-1, nominalType); }
public static StringKD forType(Class<?> nominalType)
{
if (nominalType == String.class) {
return sString;
}
if (nominalType == Object.class) {
return sObject;
}
return new StringKD(nominalType);
}
@Override
public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException {
return key;
}
}
/*
/**********************************************************
/* Key deserializer implementations; other
/**********************************************************
*/
/**
* Key deserializer that wraps a "regular" deserializer (but one
* that must recognize FIELD_NAMEs as text!) to reuse existing
* handlers as key handlers.
*/
final static class DelegatingKD
extends KeyDeserializer // note: NOT the std one
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
final protected Class<?> _keyClass;
protected final JsonDeserializer<?> _delegate;
protected DelegatingKD(Class<?> cls, JsonDeserializer<?> deser) {
_keyClass = cls;
_delegate = deser;
}
@Override
public final Object deserializeKey(String key, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
if (key == null)
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> { // is this even legal call?
return null;
}
try {
// Ugh... should not have to give parser which may or may not be correct one...
Object result = _delegate.deserialize(ctxt.getParser(), ctxt);
if (result != null) {
return result;
}
} catch (Exception re) {
throw ctxt.weirdKeyException(_keyClass, key, "not a valid representation: "+re.getMessage());
}
throw ctxt.weirdKeyException(_keyClass, key, "not a valid representation");
}
public Class<?> getKeyClass() { return _keyClass; }
}
@JacksonStdImpl
final static class EnumKD extends StdKeyDeserializer
{
private static final long serialVersionUID = 1L;
protected final EnumResolver<?> _resolver;
protected final AnnotatedMethod _factory;
protected EnumKD(EnumResolver<?> er, AnnotatedMethod factory) {
super(-1, er.getEnumClass());
_resolver = er;
_factory = factory;
}
@Override
public Object _parse(String key, DeserializationContext ctxt) throws JsonMappingException
{
if (_factory != null) {
try {
return _factory.call1(key);
} catch (Exception e) {
ClassUtil.unwrapAndThrowAsIAE(e);
}
}
Enum<?> e = _resolver.findEnum(key);
if (e == null && !ctxt.getConfig().isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) {
throw ctxt.weirdKeyException(_keyClass, key, "not one of values for Enum class");
}
return e;
}
}
/**
* Key deserializer that calls a single-string-arg constructor
* to instantiate desired key type.
*/
final static class StringCtorKeyDeserializer extends StdKeyDeserializer
{
private static final long serialVersionUID = 1L;
protected final Constructor<?> _ctor;
public StringCtorKeyDeserializer(Constructor<?> ctor) {
super(-1, ctor.getDeclaringClass());
_ctor = ctor;
}
@Override
public Object _parse(String key, DeserializationContext ctxt) throws Exception
{
return _ctor.newInstance(key);
}
}
/**
* Key deserializer that calls a static no-args factory method
* to instantiate desired key type.
*/
final static class StringFactoryKeyDeserializer extends StdKeyDeserializer
{
private static final long serialVersionUID = 1L;
final Method _factoryMethod;
public StringFactoryKeyDeserializer(Method fm) {
super(-1, fm.getDeclaringClass());
_factoryMethod = fm;
}
@Override
public Object _parse(String key, Deserial
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
/**
* Intermediate base deserializer class that adds more shared accessor
* so that other classes can access information about contained (value)
* types
*/
@SuppressWarnings("serial")
public abstract class ContainerDeserializerBase<T>
extends StdDeserializer<T>
{
protected ContainerDeserializerBase(JavaType selfType) {
super(selfType);
}
/**
* @deprecated Since 2.3 use one that takes {@link JavaType}
*/
@Deprecated
protected ContainerDeserializerBase(Class<?> selfType) {
super(selfType);
}
/*
/**********************************************************
/* Overrides
/**********************************************************
*/
@Override
public SettableBeanProperty findBackReference(String refName) {
JsonDeserializer<Object> valueDeser = getContentDeserializer();
if (valueDeser == null) {
throw new IllegalArgumentException("Can not handle managed/back reference '"+refName
+"': type: container deserializer of type "+getClass().getName()+" returned null for 'getContentDeserializer()'");
}
return valueDeser.findBackReference(refName);
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
/**
* Accessor for declared type of contained value elements; either exact
* type, or one of its supertypes.
*/
public abstract JavaType getContentType();
/**
* Accesor for deserializer use for deserializing content values.
*/
public abstract JsonDeserializer<Object> getContentDeserializer();
/*
/**********************************************************
/* Shared methods for sub-classes
/**********************************************************
*/
/**
* Helper method called by various Map(-like) deserializers.
*/
protected void wrapAndThrow(Throwable t, Object ref, String key) throws IOException
{
// to handle StackOverflow:
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
// Errors and "plain" IOExceptions to be passed as is
if (t instanceof Error) {
throw (Error) t;
}
// ... except for mapping exceptions
if (t instanceof IOException && !(t instanceof JsonMappingException)) {
throw (IOException) t;
}
throw JsonMappingException.wrapWithPath(t, ref, key);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> _fieldName; }
public int getIndex() { return _index; }
@Override public String toString() {
StringBuilder sb = new StringBuilder();
Class<?> cls = (_from instanceof Class<?>) ?
((Class<?>)_from) : _from.getClass();
/* Hmmh. Although Class.getName() is mostly ok, it does look
* butt-ugly for arrays. So let's use getSimpleName() instead;
* but have to prepend package name too.
*/
Package pkg = cls.getPackage();
if (pkg != null) {
sb.append(pkg.getName());
sb.append('.');
}
sb.append(cls.getSimpleName());
sb.append('[');
if (_fieldName != null) {
sb.append('"');
sb.append(_fieldName);
sb.append('"');
} else if (_index >= 0) {
sb.append(_index);
} else {
sb.append('?');
}
sb.append(']');
return sb.toString();
}
}
/*
/**********************************************************
/* State/configuration
/**********************************************************
*/
/**
* Path through which problem that triggering throwing of
* this exception was reached.
*/
protected LinkedList<Reference> _path;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public JsonMappingException(String msg) { super(msg); }
public JsonMappingException(String msg, Throwable rootCause) { super(msg, rootCause); }
public JsonMappingException(String msg, JsonLocation loc) { super(msg, loc); }
public JsonMappingException(String msg, JsonLocation loc, Throwable rootCause) { super(msg, loc, rootCause); }
public static JsonMappingException from(JsonParser jp, String msg) {
return new JsonMappingException(msg, ((jp == null) ? null : jp.getTokenLocation()));
}
public static JsonMappingException from(JsonParser jp, String msg, Throwable problem) {
return new JsonMappingException(msg, ((jp == null) ? null : jp.getTokenLocation()), problem);
}
/**
* Factory method used when "upgrading" an {@link IOException} into
* {@link JsonMappingException}: usually only needed to comply with
* a signature.
*
* @since 2.1
*/
public static JsonMappingException fromUnexpectedIOE(IOException src) {
return new JsonMappingException("Unexpected IOException (of type "
+src.getClass().getName()+"): "+src.getMessage(), (JsonLocation)null, src);
}
/**
* Method that can be called to either create a new JsonMappingException
* (if underlying exception is not a JsonMappingException), or augment
* given
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.introspect;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
/**
* Helper class used to introspect features of POJO value classes
* used with Jackson. The main use is for finding out
* POJO construction (creator) and value access (getters, setters)
* methods and annotations that define configuration of using
* those methods.
*/
public abstract class ClassIntrospector
{
/*
/**********************************************************
/* Helper interfaces
/**********************************************************
*/
/**
* Interface used for decoupling details of how mix-in annotation
* definitions are accessed (via this interface), and how
* they are stored (defined by classes that implement the interface)
*/
public interface MixInResolver
{
/**
* Method that will check if there are "mix-in" classes (with mix-in
* annotations) for given class
*/
public Class<?> findMixInClassFor(Class<?> cls);
}
protected ClassIntrospector() { }
/*
/**********************************************************
/* Public API: factory methods
/**********************************************************
*/
/**
* Factory method that constructs an introspector that has all
* information needed for serialization purposes.
*/
public abstract BeanDescription forSerialization(SerializationConfig cfg,
JavaType type, MixInResolver r);
/**
* Factory method that constructs an introspector that has all
* information needed for deserialization purposes.
*/
public abstract BeanDescription forDeserialization(DeserializationConfig cfg,
JavaType type, MixInResolver r);
/**
* Factory method that constructs an introspector that has all
* information needed for constructing deserializers that use
* intermediate Builder objects.
*/
public abstract BeanDescription forDeserializationWithBuilder(DeserializationConfig cfg,
JavaType type, MixInResolver r);
/**
* Factory method that constructs an introspector that has
* information necessary for creating instances of given
* class ("creator"), as well as class annotations, but
* no information on member methods
*/
public abstract BeanDescription forCreation(DeserializationConfig cfg, JavaType type,
MixInResolver r);
/**
* Factory method that constructs an introspector that only has
* information regarding annotations class itself (or its supertypes) has,
* but nothing on methods or constructors.
*/
public abstract BeanDescription forClassAnnotations(MapperConfig<?> cfg, JavaType type,
MixInResolver r);
/**
* Factory method that constructs an introspector that only has
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> And then value
if (valueElem == null) {
provider.defaultSerializeNull(jgen);
} else {
Class<?> cc = valueElem.getClass();
JsonSerializer<Object> ser = serializers.serializerFor(cc);
if (ser == null) {
if (_valueType.hasGenericTypes()) {
ser = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_valueType, cc), provider);
} else {
ser = _findAndAddDynamic(serializers, cc, provider);
}
serializers = _dynamicValueSerializers;
}
try {
if (vts == null) {
ser.serialize(valueElem, jgen, provider);
} else {
ser.serializeWithType(valueElem, jgen, provider, vts);
}
} catch (Exception e) {
// [JACKSON-55] Need to add reference information
String keyDesc = ""+keyElem;
wrapAndThrow(provider, e, value, keyDesc);
}
}
}
/**
* Method called to serialize fields, when the value type is statically known,
* so that value serializer is passed and does not need to be fetched from
* provider.
*/
protected void serializeUsing(Map.Entry<?, ?> value, JsonGenerator jgen, SerializerProvider provider,
JsonSerializer<Object> ser)
throws IOException, JsonGenerationException
{
final JsonSerializer<Object> keySerializer = _keySerializer;
final TypeSerializer vts = _valueTypeSerializer;
final boolean skipNulls = !provider.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES);
Object valueElem = value.getValue();
Object keyElem = value.getKey();
if (keyElem == null) {
provider.findNullKeySerializer(_keyType, _property).serialize(null, jgen, provider);
} else {
// [JACKSON-314] also may need to skip entries with null values
if (skipNulls && valueElem == null) return;
keySerializer.serialize(keyElem, jgen, provider);
}
if (valueElem == null) {
provider.defaultSerializeNull(jgen);
} else {
try {
if (vts == null) {
ser.serialize(valueElem, jgen, provider);
} else {
ser.serializeWithType(valueElem, jgen, provider, vts);
}
} catch (Exception e) {
// [JACKSON-55] Need to add reference information
String keyDesc = ""+keyElem;
wrapAndThrow(provider, e, value, keyDesc);
}
}
}
/*
/**********************************************************
/* Internal helper methods
/**********************************************************
*/
protected final JsonSerializer
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS><Object> _findAndAddDynamic(PropertySerializerMap map,
Class<?> type, SerializerProvider provider) throws JsonMappingException
{
PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property);
if (map != result.map) {
_dynamicValueSerializers = result.map;
}
return result.serializer;
}
protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
JavaType type, SerializerProvider provider) throws JsonMappingException
{
PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property);
if (map != result.map) {
_dynamicValueSerializers = result.map;
}
return result.serializer;
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>OBJECT</code> pairs
* need to be properly handled with respect to serializing of contents.
*
* @param value Value to serialize; can <b>not</b> be null.
* @param gen Generator used to output resulting Json content
* @param serializers Provider that can be used to get serializers for
* serializing Objects value contains, if any.
* @param typeSer Type serializer to use for including type information
*/
public void serializeWithType(T value, JsonGenerator gen, SerializerProvider serializers,
TypeSerializer typeSer)
throws IOException
{
Class<?> clz = handledType();
if (clz == null) {
clz = value.getClass();
}
throw serializers.mappingException("Type id handling not implemented for type %s (by serializer of type %s)",
clz.getName(), getClass().getName());
}
/*
/**********************************************************
/* Other accessors
/**********************************************************
*/
/**
* Method for accessing type of Objects this serializer can handle.
* Note that this information is not guaranteed to be exact -- it
* may be a more generic (super-type) -- but it should not be
* incorrect (return a non-related type).
*<p>
* Default implementation will return null, which essentially means
* same as returning <code>Object.class</code> would; that is, that
* nothing is known about handled type.
*<p>
*/
public Class<T> handledType() { return null; }
/**
* Method called to check whether given serializable value is
* considered "empty" value (for purposes of suppressing serialization
* of empty values).
*<p>
* Default implementation will consider only null values to be empty.
*
* @since 2.0
*
* @deprecated Since 2.5 Use {@link #isEmpty(SerializerProvider, Object)} instead
*/
@Deprecated
public boolean isEmpty(T value) {
return (value == null);
}
/**
* Method called to check whether given serializable value is
* considered "empty" value (for purposes of suppressing serialization
* of empty values).
*<p>
* Default implementation will consider only null values to be empty.
*<p>
* NOTE: replaces {@link #isEmpty(Object)}, deprecated in 2.5
*
* @since 2.5
*/
public boolean isEmpty(SerializerProvider provider, T value) {
// replace with implementation in 2.6 or later
return isEmpty(value);
}
/**
* Method that can be called to see whether this serializer instance
* will use Object Id to handle cyclic references.
*/
public boolean usesObjectId() {
return false;
}
/**
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
import java.lang.reflect.Type;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
@SuppressWarnings("serial")
public abstract class StdScalarSerializer<T>
extends StdSerializer<T>
{
protected StdScalarSerializer(Class<T> t) {
super(t);
}
/**
* Alternate constructor that is (alas!) needed to work
* around kinks of generic type handling
*/
@SuppressWarnings("unchecked")
protected StdScalarSerializer(Class<?> t, boolean dummy) {
super((Class<T>) t);
}
/**
* Default implementation will write type prefix, call regular serialization
* method (since assumption is that value itself does not need JSON
* Array or Object start/end markers), and then write type suffix.
* This should work for most cases; some sub-classes may want to
* change this behavior.
*/
@Override
public void serializeWithType(T value, JsonGenerator jgen, SerializerProvider provider,
TypeSerializer typeSer) throws IOException
{
typeSer.writeTypePrefixForScalar(value, jgen);
serialize(value, jgen, provider);
typeSer.writeTypeSuffixForScalar(value, jgen);
}
@Override
public JsonNode getSchema(SerializerProvider provider, Type typeHint)
throws JsonMappingException
{
return createSchemaNode("string", true);
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
throws JsonMappingException
{
if (visitor != null) {
// 13-Sep-2013, tatu: Let's assume it's usually a String, right?
// visitor.expectAnyFormat(typeHint);
visitor.expectStringFormat(typeHint);
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> jgen, SerializerProvider provider)
throws IOException, JsonGenerationException
{
if (_elementSerializer != null) {
serializeContentsUsing(value, jgen, provider, _elementSerializer);
return;
}
if (_valueTypeSerializer != null) {
serializeTypedContents(value, jgen, provider);
return;
}
final int len = value.size();
if (len == 0) {
return;
}
int i = 0;
try {
PropertySerializerMap serializers = _dynamicSerializers;
for (; i < len; ++i) {
Object elem = value.get(i);
if (elem == null) {
provider.defaultSerializeNull(jgen);
} else {
Class<?> cc = elem.getClass();
JsonSerializer<Object> serializer = serializers.serializerFor(cc);
if (serializer == null) {
// To fix [JACKSON-508]
if (_elementType.hasGenericTypes()) {
serializer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_elementType, cc), provider);
} else {
serializer = _findAndAddDynamic(serializers, cc, provider);
}
serializers = _dynamicSerializers;
}
serializer.serialize(elem, jgen, provider);
}
}
} catch (Exception e) {
wrapAndThrow(provider, e, value, i);
}
}
public void serializeContentsUsing(List<?> value, JsonGenerator jgen, SerializerProvider provider,
JsonSerializer<Object> ser)
throws IOException
{
final int len = value.size();
if (len == 0) {
return;
}
final TypeSerializer typeSer = _valueTypeSerializer;
for (int i = 0; i < len; ++i) {
Object elem = value.get(i);
try {
if (elem == null) {
provider.defaultSerializeNull(jgen);
} else if (typeSer == null) {
ser.serialize(elem, jgen, provider);
} else {
ser.serializeWithType(elem, jgen, provider, typeSer);
}
} catch (Exception e) {
// [JACKSON-55] Need to add reference information
wrapAndThrow(provider, e, value, i);
}
}
}
public void serializeTypedContents(List<?> value, JsonGenerator jgen, SerializerProvider provider)
throws IOException
{
final int len = value.size();
if (len == 0) {
return;
}
int i = 0;
try {
final TypeSerializer typeSer = _valueTypeSerializer;
PropertySerializerMap serializers = _dynamicSerializers;
for (; i < len; ++i)
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> {
Object elem = value.get(i);
if (elem == null) {
provider.defaultSerializeNull(jgen);
} else {
Class<?> cc = elem.getClass();
JsonSerializer<Object> serializer = serializers.serializerFor(cc);
if (serializer == null) {
// To fix [JACKSON-508]
if (_elementType.hasGenericTypes()) {
serializer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_elementType, cc), provider);
} else {
serializer = _findAndAddDynamic(serializers, cc, provider);
}
serializers = _dynamicSerializers;
}
serializer.serializeWithType(elem, jgen, provider, typeSer);
}
}
} catch (Exception e) {
// [JACKSON-55] Need to add reference information
wrapAndThrow(provider, e, value, i);
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> constructing {@link com.fasterxml.jackson.databind.JsonNode} instances.
*/
protected final JsonNodeFactory _nodeFactory;
/**
* States of {@link com.fasterxml.jackson.core.JsonParser.Feature}s to enable/disable.
*/
protected final int _parserFeatures;
/**
* Bitflag of {@link com.fasterxml.jackson.core.JsonParser.Feature}s to enable/disable
*/
protected final int _parserFeaturesToChange;
/*
/**********************************************************
/* Life-cycle, constructors
/**********************************************************
*/
/**
* Constructor used by ObjectMapper to create default configuration object instance.
*/
public DeserializationConfig(BaseSettings base,
SubtypeResolver str, Map<ClassKey,Class<?>> mixins)
{
super(base, str, mixins);
_deserFeatures = collectFeatureDefaults(DeserializationFeature.class);
_nodeFactory = JsonNodeFactory.instance;
_problemHandlers = null;
_parserFeatures = 0;
_parserFeaturesToChange = 0;
}
private DeserializationConfig(DeserializationConfig src,
int mapperFeatures, int deserFeatures,
int parserFeatures, int parserFeatureMask)
{
super(src, mapperFeatures);
_deserFeatures = deserFeatures;
_nodeFactory = src._nodeFactory;
_problemHandlers = src._problemHandlers;
_parserFeatures = parserFeatures;
_parserFeaturesToChange = parserFeatureMask;
}
/**
* Copy constructor used to create a non-shared instance with given mix-in
* annotation definitions and subtype resolver.
*/
private DeserializationConfig(DeserializationConfig src, SubtypeResolver str)
{
super(src, str);
_deserFeatures = src._deserFeatures;
_nodeFactory = src._nodeFactory;
_problemHandlers = src._problemHandlers;
_parserFeatures = src._parserFeatures;
_parserFeaturesToChange = src._parserFeaturesToChange;
}
private DeserializationConfig(DeserializationConfig src, BaseSettings base)
{
super(src, base);
_deserFeatures = src._deserFeatures;
_nodeFactory = src._nodeFactory;
_problemHandlers = src._problemHandlers;
_parserFeatures = src._parserFeatures;
_parserFeaturesToChange = src._parserFeaturesToChange;
}
private DeserializationConfig(DeserializationConfig src, JsonNodeFactory f)
{
super(src);
_deserFeatures = src._deserFeatures;
_problemHandlers = src._problemHandlers;
_nodeFactory = f;
_parserFeatures = src._parserFeatures;
_parserFeaturesToChange = src._parserFeaturesToChange;
}
private DeserializationConfig(DeserializationConfig src,
LinkedNode<DeserializationProblemHandler>
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> problemHandlers)
{
super(src);
_deserFeatures = src._deserFeatures;
_problemHandlers = problemHandlers;
_nodeFactory = src._nodeFactory;
_parserFeatures = src._parserFeatures;
_parserFeaturesToChange = src._parserFeaturesToChange;
}
private DeserializationConfig(DeserializationConfig src, String rootName)
{
super(src, rootName);
_deserFeatures = src._deserFeatures;
_problemHandlers = src._problemHandlers;
_nodeFactory = src._nodeFactory;
_parserFeatures = src._parserFeatures;
_parserFeaturesToChange = src._parserFeaturesToChange;
}
private DeserializationConfig(DeserializationConfig src, Class<?> view)
{
super(src, view);
_deserFeatures = src._deserFeatures;
_problemHandlers = src._problemHandlers;
_nodeFactory = src._nodeFactory;
_parserFeatures = src._parserFeatures;
_parserFeaturesToChange = src._parserFeaturesToChange;
}
/**
* @since 2.1
*/
protected DeserializationConfig(DeserializationConfig src, Map<ClassKey,Class<?>> mixins)
{
super(src, mixins);
_deserFeatures = src._deserFeatures;
_problemHandlers = src._problemHandlers;
_nodeFactory = src._nodeFactory;
_parserFeatures = src._parserFeatures;
_parserFeaturesToChange = src._parserFeaturesToChange;
}
/**
* @since 2.3
*/
protected DeserializationConfig(DeserializationConfig src, ContextAttributes attrs)
{
super(src, attrs);
_deserFeatures = src._deserFeatures;
_problemHandlers = src._problemHandlers;
_nodeFactory = src._nodeFactory;
_parserFeatures = src._parserFeatures;
_parserFeaturesToChange = src._parserFeaturesToChange;
}
// for unit tests only:
protected BaseSettings getBaseSettings() { return _base; }
/*
/**********************************************************
/* Life-cycle, factory methods from MapperConfig
/**********************************************************
*/
@Override
public DeserializationConfig with(MapperFeature... features)
{
int newMapperFlags = _mapperFeatures;
for (MapperFeature f : features) {
newMapperFlags |= f.getMask();
}
return (newMapperFlags == _mapperFeatures) ? this :
new DeserializationConfig(this, newMapperFlags, _deserFeatures,
_parserFeatures, _parserFeaturesToChange);
}
@Override
public DeserializationConfig without(MapperFeature... features)
{
int newMapperFlags = _mapperFeatures;
for (MapperFeature f : features) {
newMapperFlags &= ~f
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> ai) {
return _withBase(_base.withInsertedAnnotationIntrospector(ai));
}
@Override
public DeserializationConfig withAppendedAnnotationIntrospector(AnnotationIntrospector ai) {
return _withBase(_base.withAppendedAnnotationIntrospector(ai));
}
@Override
public DeserializationConfig withView(Class<?> view) {
return (_view == view) ? this : new DeserializationConfig(this, view);
}
@Override
public DeserializationConfig with(Locale l) {
return _withBase(_base.with(l));
}
@Override
public DeserializationConfig with(TimeZone tz) {
return _withBase(_base.with(tz));
}
@Override
public DeserializationConfig with(Base64Variant base64) {
return _withBase(_base.with(base64));
}
@Override
public DeserializationConfig with(ContextAttributes attrs) {
return (attrs == _attributes) ? this : new DeserializationConfig(this, attrs);
}
private final DeserializationConfig _withBase(BaseSettings newBase) {
return (_base == newBase) ? this : new DeserializationConfig(this, newBase);
}
/*
/**********************************************************
/* Life-cycle, DeserializationFeature-based factory methods
/**********************************************************
*/
/**
* Fluent factory method that will construct and return a new configuration
* object instance with specified features enabled.
*/
public DeserializationConfig with(DeserializationFeature feature)
{
int newDeserFeatures = (_deserFeatures | feature.getMask());
return (newDeserFeatures == _deserFeatures) ? this :
new DeserializationConfig(this, _mapperFeatures, newDeserFeatures,
_parserFeatures, _parserFeaturesToChange);
}
/**
* Fluent factory method that will construct and return a new configuration
* object instance with specified features enabled.
*/
public DeserializationConfig with(DeserializationFeature first,
DeserializationFeature... features)
{
int newDeserFeatures = _deserFeatures | first.getMask();
for (DeserializationFeature f : features) {
newDeserFeatures |= f.getMask();
}
return (newDeserFeatures == _deserFeatures) ? this :
new DeserializationConfig(this, _mapperFeatures, newDeserFeatures,
_parserFeatures, _parserFeaturesToChange);
}
/**
* Fluent factory method that will construct and return a new configuration
* object instance with specified features enabled.
*/
public DeserializationConfig withFeatures(DeserializationFeature... features)
{
int newDeserFeatures = _deserFeatures;
for (DeserializationFeature f : features) {
newDeserFeatures |= f.getMask
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.introspect;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Member;
import java.lang.reflect.Type;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeFactory;
/**
* Object that represents method parameters, mostly so that associated
* annotations can be processed conveniently. Note that many of accessors
* can not return meaningful values since parameters do not have stand-alone
* JDK objects associated; so access should mostly be limited to checking
* annotation values which are properly aggregated and included.
*/
public final class AnnotatedParameter
extends AnnotatedMember
{
private static final long serialVersionUID = 1L;
/**
* Member (method, constructor) that this parameter belongs to
*/
protected final AnnotatedWithParams _owner;
/**
* JDK type of the parameter, possibly contains generic type information
*/
protected final Type _type;
/**
* Index of the parameter within argument list
*/
protected final int _index;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public AnnotatedParameter(AnnotatedWithParams owner, Type type, AnnotationMap annotations,
int index)
{
super((owner == null) ? null : owner.getContextClass(), annotations);
_owner = owner;
_type = type;
_index = index;
}
@Override
public AnnotatedParameter withAnnotations(AnnotationMap ann) {
if (ann == _annotations) {
return this;
}
return _owner.replaceParameterAnnotations(_index, ann);
}
/*
/**********************************************************
/* Annotated impl
/**********************************************************
*/
/**
* Since there is no matching JDK element, this method will
* always return null
*/
@Override
public AnnotatedElement getAnnotated() { return null; }
/**
* Returns modifiers of the constructor, as parameters do not
* have independent modifiers.
*/
@Override
public int getModifiers() { return _owner.getModifiers(); }
/**
* Parameters have no names in bytecode (unlike in source code),
* will always return empty String ("").
*/
@Override
public String getName() { return ""; }
/**
* Accessor for annotations; all annotations associated with parameters
* are properly passed and accessible.
*/
@Override
public <A extends Annotation> A getAnnotation(Class<A> acls)
{
return (_annotations == null) ? null : _annotations.get(acls);
}
@Override
public Type getGenericType() {
return _type;
}
@Override
public Class<?> getRaw
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Type()
{
if (_type instanceof Class<?>) {
return (Class<?>) _type;
}
// 14-Mar-2011, tatu: Not optimal, but has to do for now...
JavaType t = TypeFactory.defaultInstance().constructType(_type);
return t.getRawClass();
}
/*
/**********************************************************
/* AnnotatedMember extras
/**********************************************************
*/
@Override
public Class<?> getDeclaringClass() {
return _owner.getDeclaringClass();
}
@Override
public Member getMember() {
/* This is bit tricky: since there is no JDK equivalent; can either
* return null or owner... let's do latter, for now.
*/
return _owner.getMember();
}
@Override
public void setValue(Object pojo, Object value) throws UnsupportedOperationException
{
throw new UnsupportedOperationException("Cannot call setValue() on constructor parameter of "
+getDeclaringClass().getName());
}
@Override
public Object getValue(Object pojo) throws UnsupportedOperationException
{
throw new UnsupportedOperationException("Cannot call getValue() on constructor parameter of "
+getDeclaringClass().getName());
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
public Type getParameterType() { return _type; }
/**
* Accessor for 'owner' of this parameter; method or constructor that
* has this parameter as member of its argument list.
*
* @return Owner (member or creator) object of this parameter
*/
public AnnotatedWithParams getOwner() { return _owner; }
/**
* Accessor for index of this parameter within argument list
*
* @return Index of this parameter within argument list
*/
public int getIndex() { return _index; }
/*
/********************************************************
/* Other
/********************************************************
*/
@Override
public int hashCode() {
return _owner.hashCode() + _index;
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (o == null || o.getClass() != getClass()) return false;
AnnotatedParameter other = (AnnotatedParameter) o;
return other._owner.equals(_owner) && (other._index == _index);
}
@Override
public String toString() {
return "[parameter #"+getIndex()+", annotations: "+_annotations+"]";
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.impl;
import java.util.Arrays;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
/**
* Helper container used for resolving serializers for dynamic (possibly but not
* necessarily polymorphic) properties: properties whose type is not forced
* to use dynamic (declared) type and that are not final.
* If so, serializer to use can only be established once actual value type is known.
* Since this happens a lot unless static typing is forced (or types are final)
* this implementation is optimized for efficiency.
* Instances are immutable; new instances are created with factory methods: this
* is important to ensure correct multi-threaded access.
*/
public abstract class PropertySerializerMap
{
/**
* Configuration setting that determines what happens when maximum
* size (currently 8) is reached: if true, will "start from beginning";
* if false, will simply stop adding new entries.
*
* @since 2.5
*/
protected final boolean _resetWhenFull;
/**
* @since 2.5
*/
protected PropertySerializerMap(boolean resetWhenFull) {
_resetWhenFull = resetWhenFull;
}
protected PropertySerializerMap(PropertySerializerMap base) {
_resetWhenFull = base._resetWhenFull;
}
/**
* Main lookup method. Takes a "raw" type since usage is always from
* place where parameterization is fixed such that there can not be
* type-parametric variations.
*/
public abstract JsonSerializer<Object> serializerFor(Class<?> type);
/**
* Method called if initial lookup fails, when looking for a primary
* serializer (one that is directly attached to a property).
* Will both find serializer
* and construct new map instance if warranted, and return both.
*
* @since 2.3
*
* @throws JsonMappingException
*/
public final SerializerAndMapResult findAndAddPrimarySerializer(Class<?> type,
SerializerProvider provider, BeanProperty property)
throws JsonMappingException
{
JsonSerializer<Object> serializer = provider.findPrimaryPropertySerializer(type, property);
return new SerializerAndMapResult(serializer, newWith(type, serializer));
}
public final SerializerAndMapResult findAndAddPrimarySerializer(JavaType type,
SerializerProvider provider, BeanProperty property)
throws JsonMappingException
{
JsonSerializer<Object> serializer = provider.findPrimaryPropertySerializer(type, property);
return new SerializerAndMapResult(serializer
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>, newWith(type.getRawClass(), serializer));
}
/**
* Method called if initial lookup fails, when looking for a non-primary
* serializer (one that is not directly attached to a property).
* Will both find serializer
* and construct new map instance if warranted, and return both.
*
* @since 2.3
*
* @throws JsonMappingException
*/
public final SerializerAndMapResult findAndAddSecondarySerializer(Class<?> type,
SerializerProvider provider, BeanProperty property)
throws JsonMappingException
{
JsonSerializer<Object> serializer = provider.findValueSerializer(type, property);
return new SerializerAndMapResult(serializer, newWith(type, serializer));
}
public final SerializerAndMapResult findAndAddSecondarySerializer(JavaType type,
SerializerProvider provider, BeanProperty property)
throws JsonMappingException
{
JsonSerializer<Object> serializer = provider.findValueSerializer(type, property);
return new SerializerAndMapResult(serializer, newWith(type.getRawClass(), serializer));
}
/**
* Method called if initial lookup fails, when looking for a root value
* serializer: one that is not directly attached to a property, but needs to
* have {@link com.fasterxml.jackson.databind.jsontype.TypeSerializer} wrapped
* around it. Will both find the serializer
* and construct new map instance if warranted, and return both.
*
* @since 2.5
*
* @throws JsonMappingException
*/
public final SerializerAndMapResult findAndAddRootValueSerializer(Class<?> type,
SerializerProvider provider)
throws JsonMappingException
{
JsonSerializer<Object> serializer = provider.findTypedValueSerializer(type, false, null);
return new SerializerAndMapResult(serializer, newWith(type, serializer));
}
/**
* @since 2.5
*/
public final SerializerAndMapResult findAndAddRootValueSerializer(JavaType type,
SerializerProvider provider)
throws JsonMappingException
{
JsonSerializer<Object> serializer = provider.findTypedValueSerializer(type, false, null);
return new SerializerAndMapResult(serializer, newWith(type.getRawClass(), serializer));
}
/**
* Method that can be used to 'register' a serializer that caller has resolved
* without help of this map.
*
* @since 2.5
*/
public final SerializerAndMapResult addSerializer(Class<?> type, JsonSerializer<Object> serializer) {
return new SerializerAndMapResult(serializer, newWith(type, serializer));
}
/**
* @since 2.5
*/
public final SerializerAndMapResult addSerializer(JavaType type, JsonSerializer<Object> serializer) {
return new SerializerAndMapResult
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>(serializer, newWith(type.getRawClass(), serializer));
}
public abstract PropertySerializerMap newWith(Class<?> type, JsonSerializer<Object> serializer);
/**
* @deprecated Since 2.5 Use {@link #emptyForProperties} instead
*/
@Deprecated
public static PropertySerializerMap emptyMap() {
return emptyForProperties();
}
/**
* @since 2.5
*/
public static PropertySerializerMap emptyForProperties() {
return Empty.FOR_PROPERTIES;
}
/**
* @since 2.5
*/
public static PropertySerializerMap emptyForRootValues() {
return Empty.FOR_ROOT_VALUES;
}
/*
/**********************************************************
/* Helper classes
/**********************************************************
*/
/**
* Value class used for returning tuple that has both serializer
* that was retrieved and new map instance
*/
public final static class SerializerAndMapResult
{
public final JsonSerializer<Object> serializer;
public final PropertySerializerMap map;
public SerializerAndMapResult(JsonSerializer<Object> serializer,
PropertySerializerMap map)
{
this.serializer = serializer;
this.map = map;
}
}
/**
* Trivial container for bundling type + serializer entries.
*/
private final static class TypeAndSerializer
{
public final Class<?> type;
public final JsonSerializer<Object> serializer;
public TypeAndSerializer(Class<?> type, JsonSerializer<Object> serializer) {
this.type = type;
this.serializer = serializer;
}
}
/*
/**********************************************************
/* Implementations
/**********************************************************
*/
/**
* Bogus instance that contains no serializers; used as the default
* map with new serializers.
*/
private final static class Empty extends PropertySerializerMap
{
// No root serializers; do not reset when full
public final static Empty FOR_PROPERTIES = new Empty(false);
// Yes, root serializers; do reset when full
public final static Empty FOR_ROOT_VALUES = new Empty(true);
protected Empty(boolean resetWhenFull) {
super(resetWhenFull);
}
@Override
public JsonSerializer<Object> serializerFor(Class<?> type) {
return null; // empty, nothing to find
}
@Override
public PropertySerializerMap newWith(Class<?> type, JsonSerializer<Object> serializer) {
return new Single(this, type, serializer);
}
}
/**
* Map that contains a single serializer; although seemingly silly
* this is probably the most commonly used variant because many
* theoretically dynamic or polymorphic types just have single
* actual type.
*/
private final static class Single extends PropertySerializerMap
{
private final Class<?> _type;
private final JsonSerializer<Object> _serializer;
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
public Single(PropertySerializerMap base, Class<?> type, JsonSerializer<Object> serializer) {
super(base);
_type = type;
_serializer = serializer;
}
@Override
public JsonSerializer<Object> serializerFor(Class<?> type)
{
if (type == _type) {
return _serializer;
}
return null;
}
@Override
public PropertySerializerMap newWith(Class<?> type, JsonSerializer<Object> serializer) {
return new Double(this, _type, _serializer, type, serializer);
}
}
private final static class Double extends PropertySerializerMap
{
private final Class<?> _type1, _type2;
private final JsonSerializer<Object> _serializer1, _serializer2;
public Double(PropertySerializerMap base,
Class<?> type1, JsonSerializer<Object> serializer1,
Class<?> type2, JsonSerializer<Object> serializer2)
{
super(base);
_type1 = type1;
_serializer1 = serializer1;
_type2 = type2;
_serializer2 = serializer2;
}
@Override
public JsonSerializer<Object> serializerFor(Class<?> type)
{
if (type == _type1) {
return _serializer1;
}
if (type == _type2) {
return _serializer2;
}
return null;
}
@Override
public PropertySerializerMap newWith(Class<?> type, JsonSerializer<Object> serializer) {
// Ok: let's just create generic one
TypeAndSerializer[] ts = new TypeAndSerializer[3];
ts[0] = new TypeAndSerializer(_type1, _serializer1);
ts[1] = new TypeAndSerializer(_type2, _serializer2);
ts[2] = new TypeAndSerializer(type, serializer);
return new Multi(this, ts);
}
}
private final static class Multi extends PropertySerializerMap
{
/**
* Let's limit number of serializers we actually cache; linear
* lookup won't scale too well beyond smallish number, and if
* we really want to support larger collections should use
* a hash map. But it seems unlikely this is a common use
* case so for now let's just stop building after hard-coded
* limit. 8 sounds like a reasonable stab for now.
*/
private final static int MAX_ENTRIES = 8;
private final TypeAndSerializer[] _entries;
public Multi(PropertySerializerMap base, TypeAndSerializer[] entries) {
super(base);
_entries = entries;
}
@Override
public JsonSerializer<Object> serializerFor(Class<?> type)
{
for (int i = 0, len = _entries.length; i < len; ++i)
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> {
TypeAndSerializer entry = _entries[i];
if (entry.type == type) {
return entry.serializer;
}
}
return null;
}
@Override
public PropertySerializerMap newWith(Class<?> type, JsonSerializer<Object> serializer)
{
int len = _entries.length;
// Will only grow up to N entries. We could consider couple of alternatives after
// this if we wanted to... but for now, two main choices make most sense
if (len == MAX_ENTRIES) {
if (_resetWhenFull) {
return new Single(this, type, serializer);
}
return this;
}
TypeAndSerializer[] entries = Arrays.copyOf(_entries, len+1);
entries[len] = new TypeAndSerializer(type, serializer);
return new Multi(this, entries);
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.introspect;
import java.lang.annotation.Annotation;
import java.util.*;
import com.fasterxml.jackson.databind.util.Annotations;
/**
* Simple helper class used to keep track of collection of
* Jackson Annotations associated with annotatable things
* (methods, constructors, classes).
* Note that only Jackson-owned annotations are tracked (for now?).
*/
public final class AnnotationMap implements Annotations
{
protected HashMap<Class<? extends Annotation>,Annotation> _annotations;
public AnnotationMap() { }
private AnnotationMap(HashMap<Class<? extends Annotation>,Annotation> a) {
_annotations = a;
}
@SuppressWarnings("unchecked")
@Override
public <A extends Annotation> A get(Class<A> cls)
{
if (_annotations == null) {
return null;
}
return (A) _annotations.get(cls);
}
/**
* @since 2.3
*/
public Iterable<Annotation> annotations() {
if (_annotations == null || _annotations.size() == 0) {
return Collections.emptyList();
}
return _annotations.values();
}
public static AnnotationMap merge(AnnotationMap primary, AnnotationMap secondary)
{
if (primary == null || primary._annotations == null || primary._annotations.isEmpty()) {
return secondary;
}
if (secondary == null || secondary._annotations == null || secondary._annotations.isEmpty()) {
return primary;
}
HashMap<Class<? extends Annotation>,Annotation> annotations
= new HashMap<Class<? extends Annotation>,Annotation>();
// add secondary ones first
for (Annotation ann : secondary._annotations.values()) {
annotations.put(ann.annotationType(), ann);
}
// to be overridden by primary ones
for (Annotation ann : primary._annotations.values()) {
annotations.put(ann.annotationType(), ann);
}
return new AnnotationMap(annotations);
}
@Override
public int size() {
return (_annotations == null) ? 0 : _annotations.size();
}
/**
* Method called to add specified annotation in the Map, but
* only if it didn't yet exist.
*/
public boolean addIfNotPresent(Annotation ann)
{
if (_annotations == null || !_annotations.containsKey(ann.annotationType())) {
_add(ann);
return true;
}
return false;
}
/**
* Method called to add specified annotation in the Map.
*/
public boolean add(Annotation ann) {
return _add(ann);
}
@Override
public String toString() {
if (_annotations == null) {
return "[null]";
}
return _annotations.toString();
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> /*
/**********************************************************
/* Helper methods
/**********************************************************
*/
protected final boolean _add(Annotation ann) {
if (_annotations == null) {
_annotations = new HashMap<Class<? extends Annotation>,Annotation>();
}
Annotation previous = _annotations.put(ann.annotationType(), ann);
return (previous != null) && previous.equals(ann);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitable;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsonschema.SchemaAware;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.PropertyFilter;
import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.Converter;
/**
* Base class used by all standard serializers, and can also
* be used for custom serializers (in fact, this is the recommended
* base class to use).
* Provides convenience methods for implementing {@link SchemaAware}
*/
public abstract class StdSerializer<T>
extends JsonSerializer<T>
implements JsonFormatVisitable, SchemaAware, java.io.Serializable
{
private static final long serialVersionUID = 1L;
/**
* Nominal type supported, usually declared type of
* property for which serializer is used.
*/
protected final Class<T> _handledType;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
protected StdSerializer(Class<T> t) {
_handledType = t;
}
@SuppressWarnings("unchecked")
protected StdSerializer(JavaType type) {
_handledType = (Class<T>) type.getRawClass();
}
/**
* Alternate constructor that is (alas!) needed to work
* around kinks of generic type handling
*/
@SuppressWarnings("unchecked")
protected StdSerializer(Class<?> t, boolean dummy) {
_handledType = (Class<T>) t;
}
/*
/**********************************************************
/* Accessors
/**********************************************************
*/
@Override
public Class<T> handledType() { return _handledType; }
/*
/**********************************************************
/* Serialization
/**********************************************************
*/
@Override
public abstract void serialize(T value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException;
/*
/**********************************************************
/* Helper methods for JSON Schema generation
/**********************************************************
*/
/**
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> note: pass Object.class, not Object[].class, as we need element type for error info
throw JsonMappingException.wrapWithPath(e, Object.class, result.size());
}
result.add(value);
return result;
}
public final static class CollectionReferringAccumulator {
private final Class<?> _elementType;
private final Collection<Object> _result;
/**
* A list of {@link CollectionReferring} to maintain ordering.
*/
private List<CollectionReferring> _accumulator = new ArrayList<CollectionReferring>();
public CollectionReferringAccumulator(Class<?> elementType, Collection<Object> result) {
_elementType = elementType;
_result = result;
}
public void add(Object value)
{
if (_accumulator.isEmpty()) {
_result.add(value);
} else {
CollectionReferring ref = _accumulator.get(_accumulator.size() - 1);
ref.next.add(value);
}
}
public Referring handleUnresolvedReference(UnresolvedForwardReference reference)
{
CollectionReferring id = new CollectionReferring(this, reference, _elementType);
_accumulator.add(id);
return id;
}
public void resolveForwardReference(Object id, Object value) throws IOException
{
Iterator<CollectionReferring> iterator = _accumulator.iterator();
// Resolve ordering after resolution of an id. This mean either:
// 1- adding to the result collection in case of the first unresolved id.
// 2- merge the content of the resolved id with its previous unresolved id.
Collection<Object> previous = _result;
while (iterator.hasNext()) {
CollectionReferring ref = iterator.next();
if (ref.hasId(id)) {
iterator.remove();
previous.add(value);
previous.addAll(ref.next);
return;
}
previous = ref.next;
}
throw new IllegalArgumentException("Trying to resolve a forward reference with id [" + id
+ "] that wasn't previously seen as unresolved.");
}
}
/**
* Helper class to maintain processing order of value. The resolved
* object associated with {@link #_id} comes before the values in
* {@link #next}.
*/
private final static class CollectionReferring extends Referring {
private final CollectionReferringAccumulator _parent;
public final List<Object> next = new ArrayList<Object>();
CollectionReferring(CollectionReferringAccumulator parent,
UnresolvedForwardReference reference, Class<?> contentType)
{
super(reference, contentType);
_parent = parent;
}
@Override
public void handleResolvedForwardReference(Object id, Object value) throws IOException {
_parent.resolveForwardReference(id, value);
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> byte[len]; }
}
public final static class ShortBuilder
extends PrimitiveArrayBuilder<short[]>
{
public ShortBuilder() { }
@Override
public final short[] _constructArray(int len) { return new short[len]; }
}
public final static class IntBuilder
extends PrimitiveArrayBuilder<int[]>
{
public IntBuilder() { }
@Override
public final int[] _constructArray(int len) { return new int[len]; }
}
public final static class LongBuilder
extends PrimitiveArrayBuilder<long[]>
{
public LongBuilder() { }
@Override
public final long[] _constructArray(int len) { return new long[len]; }
}
public final static class FloatBuilder
extends PrimitiveArrayBuilder<float[]>
{
public FloatBuilder() { }
@Override
public final float[] _constructArray(int len) { return new float[len]; }
}
public final static class DoubleBuilder
extends PrimitiveArrayBuilder<double[]>
{
public DoubleBuilder() { }
@Override
public final double[] _constructArray(int len) { return new double[len]; }
}
/*
/**********************************************************
/* Static helper methods
/**********************************************************
*/
/**
* Helper method used for constructing simple value comparator used for
* comparing arrays for content equality.
*<p>
* Note: current implementation is not optimized for speed; if performance
* ever becomes an issue, it is possible to construct much more efficient
* typed instances (one for Object[] and sub-types; one per primitive type).
*
* @since 2.2 Moved from earlier <code>Comparators</code> class
*/
public static Object getArrayComparator(final Object defaultValue)
{
final int length = Array.getLength(defaultValue);
final Class<?> defaultValueType = defaultValue.getClass();
return new Object() {
@Override
public boolean equals(Object other) {
if (other == this) return true;
if (other == null || other.getClass() != defaultValueType) {
return false;
}
if (Array.getLength(other) != length) return false;
// so far so good: compare actual equality; but only shallow one
for (int i = 0; i < length; ++i) {
Object value1 = Array.get(defaultValue, i);
Object value2 = Array.get(other, i);
if (value1 == value2) continue;
if (value1 != null) {
if (!value1.equals(value2)) {
return false;
}
}
}
return true;
}
};
}
public static <T> HashSet<T> arrayToSet(T[] elements)
{
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.cfg.DeserializerFactoryConfig;
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
import com.fasterxml.jackson.databind.deser.impl.CreatorCollector;
import com.fasterxml.jackson.databind.deser.std.*;
import com.fasterxml.jackson.databind.ext.OptionalHandlerFactory;
import com.fasterxml.jackson.databind.introspect.*;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
import com.fasterxml.jackson.databind.type.*;
import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.EnumResolver;
import com.fasterxml.jackson.databind.util.NameTransformer;
import com.fasterxml.jackson.databind.util.TokenBuffer;
/**
* Abstract factory base class that can provide deserializers for standard
* JDK classes, including collection classes and simple heuristics for
* "upcasting" common collection interface types
* (such as {@link java.util.Collection}).
*<p>
* Since all simple deserializers are eagerly instantiated, and there is
* no additional introspection or customizability of these types,
* this factory is stateless.
*/
@SuppressWarnings("serial")
public abstract class BasicDeserializerFactory
extends DeserializerFactory
implements java.io.Serializable
{
private final static Class<?> CLASS_OBJECT = Object.class;
private final static Class<?> CLASS_STRING = String.class;
private final static Class<?> CLASS_CHAR_BUFFER = CharSequence.class;
private final static Class<?> CLASS_ITERABLE = Iterable.class;
private final static Class<?> CLASS_MAP_ENTRY = Map.Entry.class;
/**
* We need a placeholder for creator properties that don't have name
* but are marked with `@JsonWrapped` annotation.
*/
protected final static PropertyName UNWRAPPED_CREATOR_PARAM_NAME = new PropertyName("@JsonUnwrapped");
/* We do some defaulting for abstract Map classes and
* interfaces, to avoid having to use exact types or annotations in
* cases where the most common concrete Maps will do.
*/
@
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>SuppressWarnings("rawtypes")
final static HashMap<String, Class<? extends Map>> _mapFallbacks =
new HashMap<String, Class<? extends Map>>();
static {
_mapFallbacks.put(Map.class.getName(), LinkedHashMap.class);
_mapFallbacks.put(ConcurrentMap.class.getName(), ConcurrentHashMap.class);
_mapFallbacks.put(SortedMap.class.getName(), TreeMap.class);
_mapFallbacks.put(java.util.NavigableMap.class.getName(), TreeMap.class);
_mapFallbacks.put(java.util.concurrent.ConcurrentNavigableMap.class.getName(),
java.util.concurrent.ConcurrentSkipListMap.class);
}
/* We do some defaulting for abstract Collection classes and
* interfaces, to avoid having to use exact types or annotations in
* cases where the most common concrete Collection will do.
*/
@SuppressWarnings("rawtypes")
final static HashMap<String, Class<? extends Collection>> _collectionFallbacks =
new HashMap<String, Class<? extends Collection>>();
static {
_collectionFallbacks.put(Collection.class.getName(), ArrayList.class);
_collectionFallbacks.put(List.class.getName(), ArrayList.class);
_collectionFallbacks.put(Set.class.getName(), HashSet.class);
_collectionFallbacks.put(SortedSet.class.getName(), TreeSet.class);
_collectionFallbacks.put(Queue.class.getName(), LinkedList.class);
// then 1.6 types:
/* 17-May-2013, tatu: [Issue#216] Should be fine to use straight Class references EXCEPT
* that some godforsaken platforms (... looking at you, Android) do not
* include these. So, use "soft" references...
*/
_collectionFallbacks.put("java.util.Deque", LinkedList.class);
_collectionFallbacks.put("java.util.NavigableSet", TreeSet.class);
}
/*
/**********************************************************
/* Config
/**********************************************************
*/
/**
* Configuration settings for this factory; immutable instance (just like this
* factory), new version created via copy-constructor (fluent-style)
*/
protected final DeserializerFactoryConfig _factoryConfig;
/*
/**********************************************************
/* Life cycle
/**********************************************************
*/
protected BasicDeserializerFactory(DeserializerFactoryConfig config) {
_factoryConfig = config;
}
/**
* Method for getting current {@link DeserializerFactoryConfig}.
*<p>
* Note that since instances are immutable, you can NOT change settings
* by accessing an instance and calling methods: this will simply create
* new instance of config object.
*/
public Deserial
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>izerFactoryConfig getFactoryConfig() {
return _factoryConfig;
}
protected abstract DeserializerFactory withConfig(DeserializerFactoryConfig config);
/*
/********************************************************
/* Configuration handling: fluent factories
/********************************************************
*/
/**
* Convenience method for creating a new factory instance with additional deserializer
* provider.
*/
@Override
public final DeserializerFactory withAdditionalDeserializers(Deserializers additional) {
return withConfig(_factoryConfig.withAdditionalDeserializers(additional));
}
/**
* Convenience method for creating a new factory instance with additional
* {@link KeyDeserializers}.
*/
@Override
public final DeserializerFactory withAdditionalKeyDeserializers(KeyDeserializers additional) {
return withConfig(_factoryConfig.withAdditionalKeyDeserializers(additional));
}
/**
* Convenience method for creating a new factory instance with additional
* {@link BeanDeserializerModifier}.
*/
@Override
public final DeserializerFactory withDeserializerModifier(BeanDeserializerModifier modifier) {
return withConfig(_factoryConfig.withDeserializerModifier(modifier));
}
/**
* Convenience method for creating a new factory instance with additional
* {@link AbstractTypeResolver}.
*/
@Override
public final DeserializerFactory withAbstractTypeResolver(AbstractTypeResolver resolver) {
return withConfig(_factoryConfig.withAbstractTypeResolver(resolver));
}
/**
* Convenience method for creating a new factory instance with additional
* {@link ValueInstantiators}.
*/
@Override
public final DeserializerFactory withValueInstantiators(ValueInstantiators instantiators) {
return withConfig(_factoryConfig.withValueInstantiators(instantiators));
}
/*
/**********************************************************
/* JsonDeserializerFactory impl (partial): type mappings
/**********************************************************
*/
@Override
public JavaType mapAbstractType(DeserializationConfig config, JavaType type)
throws JsonMappingException
{
// first, general mappings
while (true) {
JavaType next = _mapAbstractType2(config, type);
if (next == null) {
return type;
}
/* Should not have to worry about cycles; but better verify since they will invariably
* occur... :-)
* (also: guard against invalid resolution to a non-related type)
*/
Class<?> prevCls = type.getRawClass();
Class<?> nextCls = next.getRawClass();
if ((prevCls == nextCls) || !prevCls.isAssignableFrom(nextCls)) {
throw new IllegalArgumentException("Invalid abstract type resolution from "+type+" to "+next+": latter is not a subtype of former");
}
type = next;
}
}
/**
* Method that will find abstract type mapping for specified type, doing a single
* lookup through registered abstract type resolvers; will not do recursive lookups.
*/
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> private JavaType _mapAbstractType2(DeserializationConfig config, JavaType type)
throws JsonMappingException
{
Class<?> currClass = type.getRawClass();
if (_factoryConfig.hasAbstractTypeResolvers()) {
for (AbstractTypeResolver resolver : _factoryConfig.abstractTypeResolvers()) {
JavaType concrete = resolver.findTypeMapping(config, type);
if (concrete != null && concrete.getRawClass() != currClass) {
return concrete;
}
}
}
return null;
}
/*
/**********************************************************
/* JsonDeserializerFactory impl (partial): ValueInstantiators
/**********************************************************
*/
/**
* Value instantiator is created both based on creator annotations,
* and on optional externally provided instantiators (registered through
* module interface).
*/
@Override
public ValueInstantiator findValueInstantiator(DeserializationContext ctxt,
BeanDescription beanDesc)
throws JsonMappingException
{
final DeserializationConfig config = ctxt.getConfig();
ValueInstantiator instantiator = null;
// [JACKSON-633] Check @JsonValueInstantiator before anything else
AnnotatedClass ac = beanDesc.getClassInfo();
Object instDef = ctxt.getAnnotationIntrospector().findValueInstantiator(ac);
if (instDef != null) {
instantiator = _valueInstantiatorInstance(config, ac, instDef);
}
if (instantiator == null) {
/* Second: see if some of standard Jackson/JDK types might provide value
* instantiators.
*/
instantiator = _findStdValueInstantiator(config, beanDesc);
if (instantiator == null) {
instantiator = _constructDefaultValueInstantiator(ctxt, beanDesc);
}
}
// finally: anyone want to modify ValueInstantiator?
if (_factoryConfig.hasValueInstantiators()) {
for (ValueInstantiators insts : _factoryConfig.valueInstantiators()) {
instantiator = insts.findValueInstantiator(config, beanDesc, instantiator);
// let's do sanity check; easier to spot buggy handlers
if (instantiator == null) {
throw new JsonMappingException("Broken registered ValueInstantiators (of type "
+insts.getClass().getName()+"): returned null ValueInstantiator");
}
}
}
// Sanity check: does the chosen instantatior have incomplete creators?
if (instantiator.getIncompleteParameter() != null) {
final AnnotatedParameter nonAnnotatedParam = instantiator.getIncompleteParameter();
final AnnotatedWithParams ctor = nonAnnotatedParam.getOwner();
throw new IllegalArgumentException("Argument #"+nonAnnotatedParam.getIndex()+" of constructor "+ctor+" has no property name annotation; must have name when multiple-parameter constructor annotated as Creator");
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>[]>();
}
defs = new BeanPropertyDefinition[owner.getParameterCount()];
result.put(owner, defs);
} else {
if (defs[index] != null) {
throw new IllegalStateException("Conflict: parameter #"+index+" of "+owner
+" bound to more than one property; "+defs[index]+" vs "+propDef);
}
}
defs[index] = propDef;
}
}
return result;
}
public ValueInstantiator _valueInstantiatorInstance(DeserializationConfig config,
Annotated annotated, Object instDef)
throws JsonMappingException
{
if (instDef == null) {
return null;
}
ValueInstantiator inst;
if (instDef instanceof ValueInstantiator) {
return (ValueInstantiator) instDef;
}
if (!(instDef instanceof Class)) {
throw new IllegalStateException("AnnotationIntrospector returned key deserializer definition of type "
+instDef.getClass().getName()
+"; expected type KeyDeserializer or Class<KeyDeserializer> instead");
}
Class<?> instClass = (Class<?>)instDef;
if (ClassUtil.isBogusClass(instClass)) {
return null;
}
if (!ValueInstantiator.class.isAssignableFrom(instClass)) {
throw new IllegalStateException("AnnotationIntrospector returned Class "+instClass.getName()
+"; expected Class<ValueInstantiator>");
}
HandlerInstantiator hi = config.getHandlerInstantiator();
if (hi != null) {
inst = hi.valueInstantiatorInstance(config, annotated, instClass);
if (inst != null) {
return inst;
}
}
return (ValueInstantiator) ClassUtil.createInstance(instClass,
config.canOverrideAccessModifiers());
}
@Deprecated // since 2.5.0, removed from 2.6.0
protected void _addDeserializerConstructors(DeserializationContext ctxt, BeanDescription beanDesc, VisibilityChecker<?> vchecker,
AnnotationIntrospector intr, CreatorCollector creators)
throws JsonMappingException
{
_addDeserializerConstructors(ctxt, beanDesc, vchecker, intr, creators,
Collections.<AnnotatedWithParams,BeanPropertyDefinition[]>emptyMap());
}
protected void _addDeserializerConstructors
(DeserializationContext ctxt, BeanDescription beanDesc, VisibilityChecker<?> vchecker,
AnnotationIntrospector intr, CreatorCollector creators,
Map<AnnotatedWithParams,BeanPropertyDefinition[]> creatorParams)
throws JsonMappingException
{
// First things first: the "default constructor" (zero-arg
// constructor; whether implicit or explicit) is NOT included
// in list of constructors, so needs to be handled separately.
AnnotatedConstructor defaultCtor = beanDesc.findDefaultConstructor();
if (default
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Id(creator.getParameter(0)) != null)) {
return true;
}
if (propDef != null) {
// One more thing: if implicit name matches property with a getter
// or field, we'll consider it property-based as well
String implName = propDef.getName();
if (implName != null && !implName.isEmpty()) {
if (propDef.couldSerialize()) {
return true;
}
}
}
// in absence of everything else, default to delegating
return false;
}
protected boolean _handleSingleArgumentConstructor(DeserializationContext ctxt,
BeanDescription beanDesc, VisibilityChecker<?> vchecker,
AnnotationIntrospector intr, CreatorCollector creators,
AnnotatedConstructor ctor, boolean isCreator, boolean isVisible)
throws JsonMappingException
{
// otherwise either 'simple' number, String, or general delegate:
Class<?> type = ctor.getRawParameterType(0);
if (type == String.class || type == CharSequence.class) {
if (isCreator || isVisible) {
creators.addStringCreator(ctor, isCreator);
}
return true;
}
if (type == int.class || type == Integer.class) {
if (isCreator || isVisible) {
creators.addIntCreator(ctor, isCreator);
}
return true;
}
if (type == long.class || type == Long.class) {
if (isCreator || isVisible) {
creators.addLongCreator(ctor, isCreator);
}
return true;
}
if (type == double.class || type == Double.class) {
if (isCreator || isVisible) {
creators.addDoubleCreator(ctor, isCreator);
}
return true;
}
if (type == boolean.class || type == Boolean.class) {
if (isCreator || isVisible) {
creators.addBooleanCreator(ctor, isCreator);
}
return true;
}
// Delegating Creator ok iff it has @JsonCreator (etc)
if (isCreator) {
creators.addDelegatingCreator(ctor, isCreator, null);
return true;
}
return false;
}
@Deprecated // since 2.5, remove from 2.6
protected void _addDeserializerFactoryMethods(DeserializationContext ctxt, BeanDescription beanDesc, VisibilityChecker<?> vchecker,
AnnotationIntrospector intr, CreatorCollector creators)
throws JsonMappingException
{
_addDeserializerFactoryMethods(ctxt, beanDesc, vchecker, intr, creators,
Collections.<AnnotatedWithParams,BeanPropertyDefinition[]>emptyMap());
}
protected void _addDeserializerFactoryMethods
(DeserializationContext ctxt, BeanDescription beanDesc,
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>] = constructCreatorProperty(ctxt, beanDesc, UNWRAPPED_CREATOR_PARAM_NAME, i, param, null);
++implicitNameCount;
continue;
}
// One more thing: implicit names are ok iff ctor has creator annotation
if (isCreator) {
if (name != null && !name.isEmpty()) {
++implicitNameCount;
properties[i] = constructCreatorProperty(ctxt, beanDesc, name, i, param, injectId);
continue;
}
}
/* 25-Sep-2014, tatu: Actually, we may end up "losing" naming due to higher-priority constructor
* (see TestCreators#testConstructorCreator() test). And just to avoid running into that problem,
* let's add one more work around
*/
/*
PropertyName name2 = _findExplicitParamName(param, intr);
if (name2 != null && !name2.isEmpty()) {
// Hmmh. Ok, fine. So what are we to do with it... ?
// For now... skip. May need to revisit this, should this become problematic
continue main_loop;
}
*/
if (nonAnnotatedParam == null) {
nonAnnotatedParam = param;
}
}
final int namedCount = explicitNameCount + implicitNameCount;
// Ok: if named or injectable, we have more work to do
if (isCreator || explicitNameCount > 0 || injectCount > 0) {
// simple case; everything covered:
if ((namedCount + injectCount) == argCount) {
creators.addPropertyCreator(factory, isCreator, properties);
} else if ((explicitNameCount == 0) && ((injectCount + 1) == argCount)) {
// [712] secondary: all but one injectable, one un-annotated (un-named)
creators.addDelegatingCreator(factory, isCreator, properties);
} else { // otherwise, epic fail
throw new IllegalArgumentException("Argument #"+nonAnnotatedParam.getIndex()
+" of factory method "+factory+" has no property name annotation; must have name when multiple-parameter constructor annotated as Creator");
}
}
}
}
protected boolean _handleSingleArgumentFactory(DeserializationConfig config,
BeanDescription beanDesc, VisibilityChecker<?> vchecker,
AnnotationIntrospector intr, CreatorCollector creators,
AnnotatedMethod factory, boolean isCreator)
throws JsonMappingException
{
Class<?> type = factory.getRawParameterType(0);
if (type == String.class || type == CharSequence.class) {
if (isCreator || vchecker.isCreatorVisible(factory)) {
creators.addStringCreator(factory, isCreator);
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> BeanDescription beanDesc)
throws JsonMappingException
{
final DeserializationConfig config = ctxt.getConfig();
JavaType elemType = type.getContentType();
// Very first thing: is deserializer hard-coded for elements?
JsonDeserializer<Object> contentDeser = elemType.getValueHandler();
// Then optional type info: if type has been resolved, we may already know type deserializer:
TypeDeserializer elemTypeDeser = elemType.getTypeHandler();
// but if not, may still be possible to find:
if (elemTypeDeser == null) {
elemTypeDeser = findTypeDeserializer(config, elemType);
}
// 23-Nov-2010, tatu: Custom array deserializer?
JsonDeserializer<?> deser = _findCustomArrayDeserializer(type,
config, beanDesc, elemTypeDeser, contentDeser);
if (deser == null) {
if (contentDeser == null) {
Class<?> raw = elemType.getRawClass();
if (elemType.isPrimitive()) {
return PrimitiveArrayDeserializers.forType(raw);
} else if (raw == String.class) {
return StringArrayDeserializer.instance;
}
}
deser = new ObjectArrayDeserializer(type, contentDeser, elemTypeDeser);
}
// and then new with 2.2: ability to post-process it too (Issue#120)
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
deser = mod.modifyArrayDeserializer(config, type, beanDesc, deser);
}
}
return deser;
}
/*
/**********************************************************
/* JsonDeserializerFactory impl: Collection(-like) deserializers
/**********************************************************
*/
@Override
public JsonDeserializer<?> createCollectionDeserializer(DeserializationContext ctxt,
CollectionType type, BeanDescription beanDesc)
throws JsonMappingException
{
JavaType contentType = type.getContentType();
// Very first thing: is deserializer hard-coded for elements?
JsonDeserializer<Object> contentDeser = contentType.getValueHandler();
final DeserializationConfig config = ctxt.getConfig();
// Then optional type info (1.5): if type has been resolved, we may already know type deserializer:
TypeDeserializer contentTypeDeser = contentType.getTypeHandler();
// but if not, may still be possible to find:
if (contentTypeDeser == null) {
contentTypeDeser = findTypeDeserializer(config, contentType);
}
// 23-Nov-2010, tatu: Custom deserializer?
JsonDeserializer<?> deser = _findCustomCollectionDeserializer(type,
config, beanDesc, contentTypeDeser, contentDeser
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>);
if (deser == null) {
Class<?> collectionClass = type.getRawClass();
if (contentDeser == null) { // not defined by annotation
// One special type: EnumSet:
if (EnumSet.class.isAssignableFrom(collectionClass)) {
deser = new EnumSetDeserializer(contentType, null);
}
}
}
/* One twist: if we are being asked to instantiate an interface or
* abstract Collection, we need to either find something that implements
* the thing, or give up.
*
* Note that we do NOT try to guess based on secondary interfaces
* here; that would probably not work correctly since casts would
* fail later on (as the primary type is not the interface we'd
* be implementing)
*/
if (deser == null) {
if (type.isInterface() || type.isAbstract()) {
CollectionType implType = _mapAbstractCollectionType(type, config);
if (implType == null) {
// [Issue#292]: Actually, may be fine, but only if polymorphich deser enabled
if (type.getTypeHandler() == null) {
throw new IllegalArgumentException("Can not find a deserializer for non-concrete Collection type "+type);
}
deser = AbstractDeserializer.constructForNonPOJO(beanDesc);
} else {
type = implType;
// But if so, also need to re-check creators...
beanDesc = config.introspectForCreation(type);
}
}
if (deser == null) {
ValueInstantiator inst = findValueInstantiator(ctxt, beanDesc);
if (!inst.canCreateUsingDefault()) {
// [Issue#161]: No default constructor for ArrayBlockingQueue...
if (type.getRawClass() == ArrayBlockingQueue.class) {
return new ArrayBlockingQueueDeserializer(type, contentDeser, contentTypeDeser, inst, null);
}
}
// 13-Dec-2010, tatu: Can use more optimal deserializer if content type is String, so:
if (contentType.getRawClass() == String.class) {
// no value type deserializer because Strings are one of natural/native types:
deser = new StringCollectionDeserializer(type, contentDeser, inst);
} else {
deser = new CollectionDeserializer(type, contentDeser, contentTypeDeser, inst);
}
}
}
// and then new with 2.2: ability to post-process it too (Issue#120)
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
deser = mod.modifyCollectionDeserializer(config, type, beanDesc, deser);
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>
}
}
return deser;
}
protected CollectionType _mapAbstractCollectionType(JavaType type, DeserializationConfig config)
{
Class<?> collectionClass = type.getRawClass();
collectionClass = _collectionFallbacks.get(collectionClass.getName());
if (collectionClass == null) {
return null;
}
return (CollectionType) config.constructSpecializedType(type, collectionClass);
}
// Copied almost verbatim from "createCollectionDeserializer" -- should try to share more code
@Override
public JsonDeserializer<?> createCollectionLikeDeserializer(DeserializationContext ctxt,
CollectionLikeType type, final BeanDescription beanDesc)
throws JsonMappingException
{
JavaType contentType = type.getContentType();
// Very first thing: is deserializer hard-coded for elements?
JsonDeserializer<Object> contentDeser = contentType.getValueHandler();
final DeserializationConfig config = ctxt.getConfig();
// Then optional type info (1.5): if type has been resolved, we may already know type deserializer:
TypeDeserializer contentTypeDeser = contentType.getTypeHandler();
// but if not, may still be possible to find:
if (contentTypeDeser == null) {
contentTypeDeser = findTypeDeserializer(config, contentType);
}
JsonDeserializer<?> deser = _findCustomCollectionLikeDeserializer(type, config, beanDesc,
contentTypeDeser, contentDeser);
if (deser != null) {
// and then new with 2.2: ability to post-process it too (Issue#120)
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
deser = mod.modifyCollectionLikeDeserializer(config, type, beanDesc, deser);
}
}
}
return deser;
}
/*
/**********************************************************
/* JsonDeserializerFactory impl: Map(-like) deserializers
/**********************************************************
*/
@Override
public JsonDeserializer<?> createMapDeserializer(DeserializationContext ctxt,
MapType type, BeanDescription beanDesc)
throws JsonMappingException
{
final DeserializationConfig config = ctxt.getConfig();
JavaType keyType = type.getKeyType();
JavaType contentType = type.getContentType();
// First: is there annotation-specified deserializer for values?
@SuppressWarnings("unchecked")
JsonDeserializer<Object> contentDeser = (JsonDeserializer<Object>) contentType.getValueHandler();
// Ok: need a key deserializer (null indicates 'default' here)
KeyDeserializer keyDes = (KeyDeserializer) keyType.getValueHandler();
// Then optional type info (1.5); either attached to type, or resolved separately:
TypeDeserializer contentTypeDeser = contentType.getTypeHandler();
// but if not, may still
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> be possible to find:
if (contentTypeDeser == null) {
contentTypeDeser = findTypeDeserializer(config, contentType);
}
// 23-Nov-2010, tatu: Custom deserializer?
JsonDeserializer<?> deser = _findCustomMapDeserializer(type, config, beanDesc,
keyDes, contentTypeDeser, contentDeser);
if (deser == null) {
// Value handling is identical for all, but EnumMap requires special handling for keys
Class<?> mapClass = type.getRawClass();
if (EnumMap.class.isAssignableFrom(mapClass)) {
Class<?> kt = keyType.getRawClass();
if (kt == null || !kt.isEnum()) {
throw new IllegalArgumentException("Can not construct EnumMap; generic (key) type not available");
}
deser = new EnumMapDeserializer(type, null, contentDeser, contentTypeDeser);
}
// Otherwise, generic handler works ok.
/* But there is one more twist: if we are being asked to instantiate
* an interface or abstract Map, we need to either find something
* that implements the thing, or give up.
*
* Note that we do NOT try to guess based on secondary interfaces
* here; that would probably not work correctly since casts would
* fail later on (as the primary type is not the interface we'd
* be implementing)
*/
if (deser == null) {
if (type.isInterface() || type.isAbstract()) {
@SuppressWarnings("rawtypes")
Class<? extends Map> fallback = _mapFallbacks.get(mapClass.getName());
if (fallback != null) {
mapClass = fallback;
type = (MapType) config.constructSpecializedType(type, mapClass);
// But if so, also need to re-check creators...
beanDesc = config.introspectForCreation(type);
} else {
// [Issue#292]: Actually, may be fine, but only if polymorphich deser enabled
if (type.getTypeHandler() == null) {
throw new IllegalArgumentException("Can not find a deserializer for non-concrete Map type "+type);
}
deser = AbstractDeserializer.constructForNonPOJO(beanDesc);
}
}
if (deser == null) {
ValueInstantiator inst = findValueInstantiator(ctxt, beanDesc);
MapDeserializer md = new MapDeserializer(type, inst, keyDes, contentDeser, contentTypeDeser);
md.setIgnorableProperties(config.getAnnotationIntrospector().findPropertiesToIgnore(beanDesc.getClassInfo()));
deser = md;
}
}
}
// and then new with 2.2: ability to post-process it too
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> (Issue#120)
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
deser = mod.modifyMapDeserializer(config, type, beanDesc, deser);
}
}
return deser;
}
// Copied almost verbatim from "createMapDeserializer" -- should try to share more code
@Override
public JsonDeserializer<?> createMapLikeDeserializer(DeserializationContext ctxt,
MapLikeType type, final BeanDescription beanDesc)
throws JsonMappingException
{
JavaType keyType = type.getKeyType();
JavaType contentType = type.getContentType();
final DeserializationConfig config = ctxt.getConfig();
// First: is there annotation-specified deserializer for values?
@SuppressWarnings("unchecked")
JsonDeserializer<Object> contentDeser = (JsonDeserializer<Object>) contentType.getValueHandler();
// Ok: need a key deserializer (null indicates 'default' here)
KeyDeserializer keyDes = (KeyDeserializer) keyType.getValueHandler();
/* !!! 24-Jan-2012, tatu: NOTE: impls MUST use resolve() to find key deserializer!
if (keyDes == null) {
keyDes = p.findKeyDeserializer(config, keyType, property);
}
*/
// Then optional type info (1.5); either attached to type, or resolve separately:
TypeDeserializer contentTypeDeser = contentType.getTypeHandler();
// but if not, may still be possible to find:
if (contentTypeDeser == null) {
contentTypeDeser = findTypeDeserializer(config, contentType);
}
JsonDeserializer<?> deser = _findCustomMapLikeDeserializer(type, config,
beanDesc, keyDes, contentTypeDeser, contentDeser);
if (deser != null) {
// and then new with 2.2: ability to post-process it too (Issue#120)
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
deser = mod.modifyMapLikeDeserializer(config, type, beanDesc, deser);
}
}
}
return deser;
}
/*
/**********************************************************
/* JsonDeserializerFactory impl: Enum deserializers
/**********************************************************
*/
/**
* Factory method for constructing serializers of {@link Enum} types.
*/
@Override
public JsonDeserializer<?> createEnumDeserializer(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc)
throws JsonMappingException
{
final DeserializationConfig config = ctxt.getConfig();
final Class<?> enumClass = type.getRawClass();
// 23-Nov-2010, tatu: Custom deserializer?
JsonDeserializer<?>
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> deser = _findCustomEnumDeserializer(enumClass, config, beanDesc);
if (deser == null) {
// [JACKSON-193] May have @JsonCreator for static factory method:
for (AnnotatedMethod factory : beanDesc.getFactoryMethods()) {
if (ctxt.getAnnotationIntrospector().hasCreatorAnnotation(factory)) {
int argCount = factory.getParameterCount();
if (argCount == 1) {
Class<?> returnType = factory.getRawReturnType();
// usually should be class, but may be just plain Enum<?> (for Enum.valueOf()?)
if (returnType.isAssignableFrom(enumClass)) {
deser = EnumDeserializer.deserializerForCreator(config, enumClass, factory);
break;
}
}
throw new IllegalArgumentException("Unsuitable method ("+factory+") decorated with @JsonCreator (for Enum type "
+enumClass.getName()+")");
}
}
// [JACKSON-749] Also, need to consider @JsonValue, if one found
if (deser == null) {
deser = new EnumDeserializer(constructEnumResolver(enumClass, config, beanDesc.findJsonValueMethod()));
}
}
// and then new with 2.2: ability to post-process it too (Issue#120)
if (_factoryConfig.hasDeserializerModifiers()) {
for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) {
deser = mod.modifyEnumDeserializer(config, type, beanDesc, deser);
}
}
return deser;
}
/*
/**********************************************************
/* JsonDeserializerFactory impl: Tree deserializers
/**********************************************************
*/
@Override
public JsonDeserializer<?> createTreeDeserializer(DeserializationConfig config,
JavaType nodeType, BeanDescription beanDesc)
throws JsonMappingException
{
@SuppressWarnings("unchecked")
Class<? extends JsonNode> nodeClass = (Class<? extends JsonNode>) nodeType.getRawClass();
// 23-Nov-2010, tatu: Custom deserializer?
JsonDeserializer<?> custom = _findCustomTreeNodeDeserializer(nodeClass, config,
beanDesc);
if (custom != null) {
return custom;
}
return JsonNodeDeserializer.getDeserializer(nodeClass);
}
/*
/**********************************************************
/* JsonDeserializerFactory impl (partial): type deserializers
/**********************************************************
*/
@Override
public TypeDeserializer findTypeDeserializer(DeserializationConfig config,
JavaType baseType)
throws JsonMappingException
{
BeanDescription bean = config.introspectClassAnnotations(baseType.getRawClass());
AnnotatedClass ac = bean.getClassInfo();
AnnotationIntrospector ai = config.getAnnotationIntrospector();
TypeResolverBuilder<?> b = ai.findTypeResolver(config
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>factoryConfig.deserializerModifiers()) {
deser = mod.modifyKeyDeserializer(config, type, deser);
}
}
}
return deser;
}
private KeyDeserializer _createEnumKeyDeserializer(DeserializationContext ctxt,
JavaType type)
throws JsonMappingException
{
final DeserializationConfig config = ctxt.getConfig();
BeanDescription beanDesc = config.introspect(type);
JsonDeserializer<?> des = findDeserializerFromAnnotation(ctxt, beanDesc.getClassInfo());
if (des != null) {
return StdKeyDeserializers.constructDelegatingKeyDeserializer(config, type, des);
}
Class<?> enumClass = type.getRawClass();
// 23-Nov-2010, tatu: Custom deserializer?
JsonDeserializer<?> custom = _findCustomEnumDeserializer(enumClass, config, beanDesc);
if (custom != null) {
return StdKeyDeserializers.constructDelegatingKeyDeserializer(config, type, custom);
}
EnumResolver<?> enumRes = constructEnumResolver(enumClass, config, beanDesc.findJsonValueMethod());
// [JACKSON-193] May have @JsonCreator for static factory method:
for (AnnotatedMethod factory : beanDesc.getFactoryMethods()) {
if (config.getAnnotationIntrospector().hasCreatorAnnotation(factory)) {
int argCount = factory.getParameterCount();
if (argCount == 1) {
Class<?> returnType = factory.getRawReturnType();
// usually should be class, but may be just plain Enum<?> (for Enum.valueOf()?)
if (returnType.isAssignableFrom(enumClass)) {
// note: mostly copied from 'EnumDeserializer.deserializerForCreator(...)'
if (factory.getGenericParameterType(0) != String.class) {
throw new IllegalArgumentException("Parameter #0 type for factory method ("+factory+") not suitable, must be java.lang.String");
}
if (config.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(factory.getMember());
}
return StdKeyDeserializers.constructEnumKeyDeserializer(enumRes, factory);
}
}
throw new IllegalArgumentException("Unsuitable method ("+factory+") decorated with @JsonCreator (for Enum type "
+enumClass.getName()+")");
}
}
// [JACKSON-749] Also, need to consider @JsonValue, if one found
return StdKeyDeserializers.constructEnumKeyDeserializer(enumRes);
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
/**
* Method called to create a type information deserializer for values of
* given non-container property, if one is needed.
* If not needed (no polymorphic handling configured for property), should return null.
*
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> * @since 2.2
*/
public JsonDeserializer<?> findDefaultDeserializer(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc)
throws JsonMappingException
{
Class<?> rawType = type.getRawClass();
// Object ("untyped"), String equivalents:
if (rawType == CLASS_OBJECT) {
return new UntypedObjectDeserializer();
}
if (rawType == CLASS_STRING || rawType == CLASS_CHAR_BUFFER) {
return StringDeserializer.instance;
}
if (rawType == CLASS_ITERABLE) {
// [Issue#199]: Can and should 'upgrade' to a Collection type:
TypeFactory tf = ctxt.getTypeFactory();
JavaType[] tps = tf.findTypeParameters(type, CLASS_ITERABLE);
JavaType elemType = (tps == null || tps.length != 1) ? TypeFactory.unknownType() : tps[0];
CollectionType ct = tf.constructCollectionType(Collection.class, elemType);
// Should we re-introspect beanDesc? For now let's not...
return createCollectionDeserializer(ctxt, ct, beanDesc);
}
if (rawType == CLASS_MAP_ENTRY) {
final DeserializationConfig config = ctxt.getConfig();
TypeFactory tf = ctxt.getTypeFactory();
JavaType[] tps = tf.findTypeParameters(type, CLASS_MAP_ENTRY);
JavaType kt, vt;
if (tps == null || tps.length != 2) {
kt = vt = TypeFactory.unknownType();
} else {
kt = tps[0];
vt = tps[1];
}
TypeDeserializer vts = (TypeDeserializer) vt.getTypeHandler();
if (vts == null) {
vts = findTypeDeserializer(config, vt);
}
JsonDeserializer<Object> valueDeser = vt.getValueHandler();
KeyDeserializer keyDes = (KeyDeserializer) kt.getValueHandler();
return new MapEntryDeserializer(type, keyDes, valueDeser, vts);
}
String clsName = rawType.getName();
if (rawType.isPrimitive() || clsName.startsWith("java.")) {
// Primitives/wrappers, other Numbers:
JsonDeserializer<?> deser = NumberDeserializers.find(rawType, clsName);
if (deser == null) {
deser = DateDeserializers.find(rawType, clsName);
}
if (deser != null) {
return deser;
}
}
// and a few Jackson types as well:
if (rawType == TokenBuffer.class) {
return new TokenBufferDeserializer();
}
if (AtomicReference.class.isAssignableFrom(rawType)) {
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>MappingException
{
for (Deserializers d : _factoryConfig.deserializers()) {
JsonDeserializer<?> deser = d.findCollectionLikeDeserializer(type, config, beanDesc,
elementTypeDeserializer, elementDeserializer);
if (deser != null) {
return deser;
}
}
return null;
}
protected JsonDeserializer<?> _findCustomEnumDeserializer(Class<?> type,
DeserializationConfig config, BeanDescription beanDesc)
throws JsonMappingException
{
for (Deserializers d : _factoryConfig.deserializers()) {
JsonDeserializer<?> deser = d.findEnumDeserializer(type, config, beanDesc);
if (deser != null) {
return deser;
}
}
return null;
}
protected JsonDeserializer<?> _findCustomMapDeserializer(MapType type,
DeserializationConfig config, BeanDescription beanDesc,
KeyDeserializer keyDeserializer,
TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer)
throws JsonMappingException
{
for (Deserializers d : _factoryConfig.deserializers()) {
JsonDeserializer<?> deser = d.findMapDeserializer(type, config, beanDesc,
keyDeserializer, elementTypeDeserializer, elementDeserializer);
if (deser != null) {
return deser;
}
}
return null;
}
protected JsonDeserializer<?> _findCustomMapLikeDeserializer(MapLikeType type,
DeserializationConfig config, BeanDescription beanDesc,
KeyDeserializer keyDeserializer,
TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer)
throws JsonMappingException
{
for (Deserializers d : _factoryConfig.deserializers()) {
JsonDeserializer<?> deser = d.findMapLikeDeserializer(type, config, beanDesc,
keyDeserializer, elementTypeDeserializer, elementDeserializer);
if (deser != null) {
return deser;
}
}
return null;
}
protected JsonDeserializer<?> _findCustomTreeNodeDeserializer(Class<? extends JsonNode> type,
DeserializationConfig config, BeanDescription beanDesc)
throws JsonMappingException
{
for (Deserializers d : _factoryConfig.deserializers()) {
JsonDeserializer<?> deser = d.findTreeNodeDeserializer(type, config, beanDesc);
if (deser != null) {
return deser;
}
}
return null;
}
/*
/**********************************************************
/* Helper methods, value/content/key type introspection
/**********************************************************
*/
/**
* Helper method called to check if a class or method
* has annotation that tells which class to use for deserialization.
* Returns null if no such annotation found.
*/
protected JsonDeserializer<Object> findDeserializerFromAnnotation(DeserializationContext ctxt,
Annotated ann)
throws JsonMappingException
{
Object deserDef = ctxt.
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>getAnnotationIntrospector().findDeserializer(ann);
if (deserDef == null) {
return null;
}
return ctxt.deserializerInstance(ann, deserDef);
}
/**
* Method called to see if given method has annotations that indicate
* a more specific type than what the argument specifies.
* If annotations are present, they must specify compatible Class;
* instance of which can be assigned using the method. This means
* that the Class has to be raw class of type, or its sub-class
* (or, implementing class if original Class instance is an interface).
*
* @param a Method or field that the type is associated with
* @param type Type of field, or the setter argument
*
* @return Original type if no annotations are present; or a more
* specific type derived from it if type annotation(s) was found
*
* @throws JsonMappingException if invalid annotation is found
*/
@SuppressWarnings({ "unchecked" })
protected <T extends JavaType> T modifyTypeByAnnotation(DeserializationContext ctxt,
Annotated a, T type)
throws JsonMappingException
{
// first: let's check class for the instance itself:
AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
Class<?> subclass = intr.findDeserializationType(a, type);
if (subclass != null) {
try {
type = (T) type.narrowBy(subclass);
} catch (IllegalArgumentException iae) {
throw new JsonMappingException("Failed to narrow type "+type+" with concrete-type annotation (value "+subclass.getName()+"), method '"+a.getName()+"': "+iae.getMessage(), null, iae);
}
}
// then key class
if (type.isContainerType()) {
Class<?> keyClass = intr.findDeserializationKeyType(a, type.getKeyType());
if (keyClass != null) {
// illegal to use on non-Maps
if (!(type instanceof MapLikeType)) {
throw new JsonMappingException("Illegal key-type annotation: type "+type+" is not a Map(-like) type");
}
try {
type = (T) ((MapLikeType) type).narrowKey(keyClass);
} catch (IllegalArgumentException iae) {
throw new JsonMappingException("Failed to narrow key type "+type+" with key-type annotation ("+keyClass.getName()+"): "+iae.getMessage(), null, iae);
}
}
JavaType keyType = type.getKeyType();
/* 21-Mar-2011, tatu: ... and associated deserializer too (unless already assigned)
* (not 100% why or how, but this does seem to get called more than once, which
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> * is not good: for now, let's just avoid errors)
*/
if (keyType != null && keyType.getValueHandler() == null) {
Object kdDef = intr.findKeyDeserializer(a);
KeyDeserializer kd = ctxt.keyDeserializerInstance(a, kdDef);
if (kd != null) {
type = (T) ((MapLikeType) type).withKeyValueHandler(kd);
keyType = type.getKeyType(); // just in case it's used below
}
}
// and finally content class; only applicable to structured types
Class<?> cc = intr.findDeserializationContentType(a, type.getContentType());
if (cc != null) {
try {
type = (T) type.narrowContentsBy(cc);
} catch (IllegalArgumentException iae) {
throw new JsonMappingException("Failed to narrow content type "+type+" with content-type annotation ("+cc.getName()+"): "+iae.getMessage(), null, iae);
}
}
// ... as well as deserializer for contents:
JavaType contentType = type.getContentType();
if (contentType.getValueHandler() == null) { // as with above, avoid resetting (which would trigger exception)
Object cdDef = intr.findContentDeserializer(a);
JsonDeserializer<?> cd = ctxt.deserializerInstance(a, cdDef);
if (cd != null) {
type = (T) type.withContentValueHandler(cd);
}
}
}
return type;
}
/**
* Helper method used to resolve method return types and field
* types. The main trick here is that the containing bean may
* have type variable binding information (when deserializing
* using generic type passed as type reference), which is
* needed in some cases.
*/
protected JavaType resolveType(DeserializationContext ctxt,
BeanDescription beanDesc, JavaType type, AnnotatedMember member)
throws JsonMappingException
{
// [JACKSON-154]: Also need to handle keyUsing, contentUsing
if (type.isContainerType()) {
AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
JavaType keyType = type.getKeyType();
if (keyType != null) {
Object kdDef = intr.findKeyDeserializer(member);
KeyDeserializer kd = ctxt.keyDeserializerInstance(member, kdDef);
if (kd != null) {
type = ((MapLikeType) type).withKeyValueHandler(kd);
keyType = type.getKeyType(); // just in case it's used below
}
}
// and all container types have content types...
Object cdDef = intr.findContentDeserializer(member);
JsonDeserializer<?> cd = ctxt.deserializer
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Instance(member, cdDef);
if (cd != null) {
type = type.withContentValueHandler(cd);
}
/* 04-Feb-2010, tatu: Need to figure out JAXB annotations that indicate type
* information to use for polymorphic members; and specifically types for
* collection values (contents).
* ... but only applies to members (fields, methods), not classes
*/
if (member instanceof AnnotatedMember) {
TypeDeserializer contentTypeDeser = findPropertyContentTypeDeserializer(
ctxt.getConfig(), type, (AnnotatedMember) member);
if (contentTypeDeser != null) {
type = type.withContentTypeHandler(contentTypeDeser);
}
}
}
TypeDeserializer valueTypeDeser;
if (member instanceof AnnotatedMember) { // JAXB allows per-property annotations
valueTypeDeser = findPropertyTypeDeserializer(ctxt.getConfig(),
type, (AnnotatedMember) member);
} else { // classes just have Jackson annotations
// probably only occurs if 'property' is null anyway
valueTypeDeser = findTypeDeserializer(ctxt.getConfig(), type);
}
if (valueTypeDeser != null) {
type = type.withTypeHandler(valueTypeDeser);
}
return type;
}
protected EnumResolver<?> constructEnumResolver(Class<?> enumClass,
DeserializationConfig config, AnnotatedMethod jsonValueMethod)
{
if (jsonValueMethod != null) {
Method accessor = jsonValueMethod.getAnnotated();
if (config.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(accessor);
}
return EnumResolver.constructUnsafeUsingMethod(enumClass, accessor);
}
// [JACKSON-212]: may need to use Enum.toString()
if (config.isEnabled(DeserializationFeature.READ_ENUMS_USING_TO_STRING)) {
return EnumResolver.constructUnsafeUsingToString(enumClass);
}
return EnumResolver.constructUnsafe(enumClass, config.getAnnotationIntrospector());
}
protected AnnotatedMethod _findJsonValueFor(DeserializationConfig config, JavaType enumType)
{
if (enumType == null) {
return null;
}
BeanDescription beanDesc = config.introspect(enumType);
return beanDesc.findJsonValueMethod();
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>ined access to configuration features
/* (usually based on annotations)
/* Since most trivial implementations do not support
/* these methods, they are implemented as no-ops.
/**********************************************************
*/
/**
* Method used to find View-inclusion definitions for the property.
*/
public Class<?>[] findViews() { return null; }
/**
* Method used to find whether property is part of a bi-directional
* reference.
*/
public AnnotationIntrospector.ReferenceProperty findReferenceType() { return null; }
/**
* Method used to check whether this logical property has a marker
* to indicate it should be used as the type id for polymorphic type
* handling.
*/
public boolean isTypeId() { return false; }
/**
* Method used to check whether this logical property indicates that
* value POJOs should be written using additional Object Identifier
* (or, when multiple references exist, all but first AS Object Identifier).
*/
public ObjectIdInfo findObjectIdInfo() { return null; }
/**
* Method used to check if this property is expected to have a value;
* and if none found, should either be considered invalid (and most likely
* fail deserialization), or handled by other means (by providing default
* value)
*/
public boolean isRequired() {
PropertyMetadata md = getMetadata();
return (md != null) && md.isRequired();
}
/**
* Method used to check if this property has specific inclusion override
* associated with it or not.
*
* @since 2.5
*/
public JsonInclude.Include findInclusion() {
return null;
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> * {@link BeanDeserializerModifier}.
*/
public abstract DeserializerFactory withDeserializerModifier(BeanDeserializerModifier modifier);
/**
* Convenience method for creating a new factory instance with additional
* {@link AbstractTypeResolver}.
*/
public abstract DeserializerFactory withAbstractTypeResolver(AbstractTypeResolver resolver);
/**
* Convenience method for creating a new factory instance with additional
* {@link ValueInstantiators}.
*/
public abstract DeserializerFactory withValueInstantiators(ValueInstantiators instantiators);
/*
/**********************************************************
/* Basic DeserializerFactory API:
/**********************************************************
*/
/**
* Method that can be called to try to resolve an abstract type
* (interface, abstract class) into a concrete type, or at least
* something "more concrete" (abstract class instead of interface).
* Will either return passed type, or a more specific type.
*/
public abstract JavaType mapAbstractType(DeserializationConfig config, JavaType type)
throws JsonMappingException;
/**
* Method that is to find all creators (constructors, factory methods)
* for the bean type to deserialize.
*/
public abstract ValueInstantiator findValueInstantiator(DeserializationContext ctxt,
BeanDescription beanDesc)
throws JsonMappingException;
/**
* Method called to create (or, for completely immutable deserializers,
* reuse) a deserializer that can convert JSON content into values of
* specified Java "bean" (POJO) type.
* At this point it is known that the type is not otherwise recognized
* as one of structured types (array, Collection, Map) or a well-known
* JDK type (enum, primitives/wrappers, String); this method only
* gets called if other options are exhausted. This also means that
* this method can be overridden to add support for custom types.
*
* @param type Type to be deserialized
*/
public abstract JsonDeserializer<Object> createBeanDeserializer(DeserializationContext ctxt,
JavaType type, BeanDescription beanDesc)
throws JsonMappingException;
/**
* Method called to create a deserializer that will use specified Builder
* class for building value instances.
*
* @since 2.0
*/
public abstract JsonDeserializer<Object> createBuilderBasedDeserializer(
DeserializationContext ctxt, JavaType type, BeanDescription beanDesc,
Class<?> builderClass)
throws JsonMappingException;
/**
* Method called to create (or, for completely immutable deserializers,
* reuse) a deserializer that can convert JSON content into values of
* specified Java type.
*
* @param type Type to be deserialized
*/
public abstract JsonDeserializer<?> createArrayDeserializer(DeserializationContext ctxt,
ArrayType type, BeanDescription beanDesc)
throws JsonMappingException;
public abstract JsonDeserializer<?> create
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import java.lang.reflect.Array;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.type.ArrayType;
import com.fasterxml.jackson.databind.util.ObjectBuffer;
/**
* Basic serializer that can serialize non-primitive arrays.
*/
@JacksonStdImpl
public class ObjectArrayDeserializer
extends ContainerDeserializerBase<Object[]>
implements ContextualDeserializer
{
private static final long serialVersionUID = 1L;
// // Configuration
/**
* Full generic type of the array being deserialized
*/
protected final ArrayType _arrayType;
/**
* Flag that indicates whether the component type is Object or not.
* Used for minor optimization when constructing result.
*/
protected final boolean _untyped;
/**
* Type of contained elements: needed for constructing actual
* result array
*/
protected final Class<?> _elementClass;
/**
* Element deserializer
*/
protected JsonDeserializer<Object> _elementDeserializer;
/**
* If element instances have polymorphic type information, this
* is the type deserializer that can handle it
*/
protected final TypeDeserializer _elementTypeDeserializer;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public ObjectArrayDeserializer(ArrayType arrayType,
JsonDeserializer<Object> elemDeser, TypeDeserializer elemTypeDeser)
{
super(arrayType);
_arrayType = arrayType;
_elementClass = arrayType.getContentType().getRawClass();
_untyped = (_elementClass == Object.class);
_elementDeserializer = elemDeser;
_elementTypeDeserializer = elemTypeDeser;
}
/**
* Overridable fluent-factory method used to create contextual instances
*/
@SuppressWarnings("unchecked")
public ObjectArrayDeserializer withDeserializer(TypeDeserializer elemTypeDeser,
JsonDeserializer<?> elemDeser)
{
if ((elemDeser == _elementDeserializer) && (elemTypeDeser == _elementTypeDeserializer)) {
return this;
}
return new ObjectArrayDeserializer(_arrayType,
(JsonDeserializer<Object>) elemDeser, elemTypeDeser);
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
BeanProperty property) throws JsonMappingException
{
JsonDeserializer<?> deser = _elementDeserializer;
// #125: May have a content converter
deser = find
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> value.size();
if ((len == 1) && provider.isEnabled(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED)) {
serializeContents(value, jgen, provider);
return;
}
jgen.writeStartArray(len);
serializeContents(value, jgen, provider);
jgen.writeEndArray();
}
@Override
public void serializeContents(Collection<?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException
{
if (_elementSerializer != null) {
serializeContentsUsing(value, jgen, provider, _elementSerializer);
return;
}
Iterator<?> it = value.iterator();
if (!it.hasNext()) {
return;
}
PropertySerializerMap serializers = _dynamicSerializers;
final TypeSerializer typeSer = _valueTypeSerializer;
int i = 0;
try {
do {
Object elem = it.next();
if (elem == null) {
provider.defaultSerializeNull(jgen);
} else {
Class<?> cc = elem.getClass();
JsonSerializer<Object> serializer = serializers.serializerFor(cc);
if (serializer == null) {
// To fix [JACKSON-508]
if (_elementType.hasGenericTypes()) {
serializer = _findAndAddDynamic(serializers,
provider.constructSpecializedType(_elementType, cc), provider);
} else {
serializer = _findAndAddDynamic(serializers, cc, provider);
}
serializers = _dynamicSerializers;
}
if (typeSer == null) {
serializer.serialize(elem, jgen, provider);
} else {
serializer.serializeWithType(elem, jgen, provider, typeSer);
}
}
++i;
} while (it.hasNext());
} catch (Exception e) {
// [JACKSON-55] Need to add reference information
wrapAndThrow(provider, e, value, i);
}
}
public void serializeContentsUsing(Collection<?> value, JsonGenerator jgen, SerializerProvider provider,
JsonSerializer<Object> ser)
throws IOException, JsonGenerationException
{
Iterator<?> it = value.iterator();
if (it.hasNext()) {
TypeSerializer typeSer = _valueTypeSerializer;
int i = 0;
do {
Object elem = it.next();
try {
if (elem == null) {
provider.defaultSerializeNull(jgen);
} else {
if (typeSer == null) {
ser.serialize(elem, jgen, provider);
} else {
ser.serializeWithType(elem, jgen, provider, typeSer);
}
}
++i;
} catch (Exception e) {
// [JACKSON-
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> return deserializeFromArray(p, ctxt);
case FIELD_NAME:
case END_OBJECT: // added to resolve [JACKSON-319], possible related issues
if (_vanillaProcessing) {
return vanillaDeserialize(p, ctxt, t);
}
if (_objectIdReader != null) {
return deserializeWithObjectId(p, ctxt);
}
return deserializeFromObject(p, ctxt);
default:
throw ctxt.mappingException(handledType());
}
}
protected Object _missingToken(JsonParser p, DeserializationContext ctxt)
throws JsonProcessingException
{
throw ctxt.endOfInputException(handledType());
}
/**
* Secondary deserialization method, called in cases where POJO
* instance is created as part of deserialization, potentially
* after collecting some or all of the properties to set.
*/
@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt, Object bean)
throws IOException
{
// [databind#631]: Assign current value, to be accessible by custom serializers
p.setCurrentValue(bean);
if (_injectables != null) {
injectValues(ctxt, bean);
}
if (_unwrappedPropertyHandler != null) {
return deserializeWithUnwrapped(p, ctxt, bean);
}
if (_externalTypeIdHandler != null) {
return deserializeWithExternalTypeId(p, ctxt, bean);
}
JsonToken t = p.getCurrentToken();
// 23-Mar-2010, tatu: In some cases, we start with full JSON object too...
if (t == JsonToken.START_OBJECT) {
t = p.nextToken();
}
if (_needViewProcesing) {
Class<?> view = ctxt.getActiveView();
if (view != null) {
return deserializeWithView(p, ctxt, bean, view);
}
}
for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
String propName = p.getCurrentName();
p.nextToken();
if (!_beanProperties.findDeserializeAndSet(p, ctxt, bean, propName)) {
handleUnknownVanilla(p, ctxt, bean, propName);
}
}
return bean;
}
/*
/**********************************************************
/* Concrete deserialization methods
/**********************************************************
*/
/**
* Streamlined version that is only used when no "special"
* features are enabled.
*/
private final Object vanillaDeserialize(JsonParser p,
DeserializationContext ctxt, JsonToken t)
throws IOException
{
final Object bean = _valueInstantiator.createUsingDefault(ctxt);
// [databind#631]: Assign current value, to be accessible by custom serializers
p.setCurrentValue(
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> view = ctxt.getActiveView();
if (view != null) {
return deserializeWithView(p, ctxt, bean, view);
}
}
*/
return bean;
}
final Object bean = _valueInstantiator.createUsingDefault(ctxt);
// [databind#631]: Assign current value, to be accessible by custom deserializers
p.setCurrentValue(bean);
if (p.canReadObjectId()) {
Object id = p.getObjectId();
if (id != null) {
_handleTypedObjectId(p, ctxt, bean, id);
}
}
if (_injectables != null) {
injectValues(ctxt, bean);
}
if (_needViewProcesing) {
Class<?> view = ctxt.getActiveView();
if (view != null) {
return deserializeWithView(p, ctxt, bean, view);
}
}
JsonToken t = p.getCurrentToken();
for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
String propName = p.getCurrentName();
p.nextToken();
if (!_beanProperties.findDeserializeAndSet(p, ctxt, bean, propName)) {
handleUnknownVanilla(p, ctxt, bean, propName);
}
}
// 13-Dec-2014, tatu: For 2.6, we'll do:
/*
if (p.hasTokenId(JsonTokenId.ID_FIELD_NAME)) {
String propName = p.getCurrentName();
do {
p.nextToken();
if (!_beanProperties.findDeserializeAndSet(p, ctxt, bean, propName)) {
handleUnknownVanilla(p, ctxt, bean, propName);
}
} while ((propName = p.nextFieldName()) != null);
}
*/
return bean;
}
/**
* Method called to deserialize bean using "property-based creator":
* this means that a non-default constructor or factory method is
* called, and then possibly other setters. The trick is that
* values for creator method need to be buffered, first; and
* due to non-guaranteed ordering possibly some other properties
* as well.
*/
@Override
@SuppressWarnings("resource")
protected Object _deserializeUsingPropertyBased(final JsonParser p, final DeserializationContext ctxt)
throws IOException
{
final PropertyBasedCreator creator = _propertyBasedCreator;
PropertyValueBuffer buffer = creator.startBuilding(p, ctxt, _objectIdReader);
// 04-Jan-2010, tatu: May need to collect unknown properties for polymorphic cases
TokenBuffer unknown = null;
JsonToken t = p.getCurrentToken();
for (; t == JsonToken
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> e) {
wrapInstantiationProblem(e, ctxt);
bean = null; // never gets here
}
if (unknown != null) {
// polymorphic?
if (bean.getClass() != _beanType.getRawClass()) {
return handlePolymorphic(null, ctxt, bean, unknown);
}
// no, just some extra unknown properties
return handleUnknownProperties(ctxt, bean, unknown);
}
return bean;
}
/*
/**********************************************************
/* Deserializing when we have to consider an active View
/**********************************************************
*/
protected final Object deserializeWithView(JsonParser p, DeserializationContext ctxt,
Object bean, Class<?> activeView)
throws IOException
{
JsonToken t = p.getCurrentToken();
for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
String propName = p.getCurrentName();
// Skip field name:
p.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) {
if (!prop.visibleInView(activeView)) {
p.skipChildren();
continue;
}
try {
prop.deserializeAndSet(p, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
handleUnknownVanilla(p, ctxt, bean, propName);
}
return bean;
}
/*
/**********************************************************
/* Handling for cases where we have "unwrapped" values
/**********************************************************
*/
/**
* Method called when there are declared "unwrapped" properties
* which need special handling
*/
@SuppressWarnings("resource")
protected Object deserializeWithUnwrapped(JsonParser p, DeserializationContext ctxt)
throws IOException
{
if (_delegateDeserializer != null) {
return _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(p, ctxt));
}
if (_propertyBasedCreator != null) {
return deserializeUsingPropertyBasedWithUnwrapped(p, ctxt);
}
TokenBuffer tokens = new TokenBuffer(p);
tokens.writeStartObject();
final Object bean = _valueInstantiator.createUsingDefault(ctxt);
// [databind#631]: Assign current value, to be accessible by custom serializers
p.setCurrentValue(bean);
if (_injectables != null) {
injectValues(ctxt, bean);
}
final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
JsonToken t = p.getCurrentToken();
for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
String propName = p.getCurrentName();
p.nextToken();
Set
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>tableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) { // normal case
if (activeView != null && !prop.visibleInView(activeView)) {
p.skipChildren();
continue;
}
try {
prop.deserializeAndSet(p, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
// ignorable things should be ignored
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(p, ctxt, bean, propName);
continue;
}
// but... others should be passed to unwrapped property deserializers
tokens.writeFieldName(propName);
tokens.copyCurrentStructure(p);
// how about any setter? We'll get copies but...
if (_anySetter != null) {
try {
_anySetter.deserializeAndSet(p, ctxt, bean, propName);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
}
tokens.writeEndObject();
_unwrappedPropertyHandler.processUnwrapped(p, ctxt, bean, tokens);
return bean;
}
@SuppressWarnings("resource")
protected Object deserializeWithUnwrapped(JsonParser p, DeserializationContext ctxt, Object bean)
throws IOException
{
JsonToken t = p.getCurrentToken();
if (t == JsonToken.START_OBJECT) {
t = p.nextToken();
}
TokenBuffer tokens = new TokenBuffer(p);
tokens.writeStartObject();
final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
String propName = p.getCurrentName();
SettableBeanProperty prop = _beanProperties.find(propName);
p.nextToken();
if (prop != null) { // normal case
if (activeView != null && !prop.visibleInView(activeView)) {
p.skipChildren();
continue;
}
try {
prop.deserializeAndSet(p, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(p, ctxt, bean, propName);
continue;
}
// but... others should be passed to unwrapped property deserializers
tokens.writeFieldName(propName);
tokens.copyCurrentStructure(p);
// how about any setter? We'll
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> continue;
}
/* As per [JACKSON-313], things marked as ignorable should not be
* passed to any setter
*/
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnoredProperty(p, ctxt, handledType(), propName);
continue;
}
tokens.writeFieldName(propName);
tokens.copyCurrentStructure(p);
// "any property"?
if (_anySetter != null) {
buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(p, ctxt));
}
}
// We hit END_OBJECT, so:
Object bean;
try {
bean = creator.build(ctxt, buffer);
} catch (Exception e) {
wrapInstantiationProblem(e, ctxt);
return null; // never gets here
}
return _unwrappedPropertyHandler.processUnwrapped(p, ctxt, bean, tokens);
}
/*
/**********************************************************
/* Handling for cases where we have property/-ies with
/* external type id
/**********************************************************
*/
protected Object deserializeWithExternalTypeId(JsonParser p, DeserializationContext ctxt)
throws IOException
{
if (_propertyBasedCreator != null) {
return deserializeUsingPropertyBasedWithExternalTypeId(p, ctxt);
}
return deserializeWithExternalTypeId(p, ctxt, _valueInstantiator.createUsingDefault(ctxt));
}
protected Object deserializeWithExternalTypeId(JsonParser p, DeserializationContext ctxt,
Object bean)
throws IOException
{
final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
final ExternalTypeHandler ext = _externalTypeIdHandler.start();
for (JsonToken t = p.getCurrentToken(); t == JsonToken.FIELD_NAME; t = p.nextToken()) {
String propName = p.getCurrentName();
t = p.nextToken();
SettableBeanProperty prop = _beanProperties.find(propName);
if (prop != null) { // normal case
// [JACKSON-831]: may have property AND be used as external type id:
if (t.isScalarValue()) {
ext.handleTypePropertyValue(p, ctxt, propName, bean);
}
if (activeView != null && !prop.visibleInView(activeView)) {
p.skipChildren();
continue;
}
try {
prop.deserializeAndSet(p, ctxt, bean);
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
// ignorable things should be ignored
if (_ignorableProps != null && _ignorableProps.contains(propName)) {
handleIgnored
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> id property being optional,
* so let's consider required at this point.
*/
ObjectIdValueProperty prop = new ObjectIdValueProperty(_objectIdReader, PropertyMetadata.STD_REQUIRED);
propertyMap = propertyMap.withProperty(prop);
}
return new BeanDeserializer(this,
_beanDesc, propertyMap, _backRefProperties, _ignorableProps, _ignoreAllUnknown,
anyViews);
}
/**
* Alternate build method used when we must be using some form of
* abstract resolution, usually by using addition Type Id
* ("polymorphic deserialization")
*
* @since 2.0
*/
public AbstractDeserializer buildAbstract() {
return new AbstractDeserializer(this, _beanDesc, _backRefProperties);
}
/**
* Method for constructing a specialized deserializer that uses
* additional external Builder object during data binding.
*/
public JsonDeserializer<?> buildBuilderBased(JavaType valueType,
String expBuildMethodName)
{
// First: validation; must have build method that returns compatible type
if (_buildMethod == null) {
throw new IllegalArgumentException("Builder class "+_beanDesc.getBeanClass().getName()
+" does not have build method '"+expBuildMethodName+"()'");
}
// also: type of the method must be compatible
Class<?> rawBuildType = _buildMethod.getRawReturnType();
if (!valueType.getRawClass().isAssignableFrom(rawBuildType)) {
throw new IllegalArgumentException("Build method '"+_buildMethod.getFullName()
+" has bad return type ("+rawBuildType.getName()
+"), not compatible with POJO type ("+valueType.getRawClass().getName()+")");
}
// And if so, we can try building the deserializer
Collection<SettableBeanProperty> props = _properties.values();
BeanPropertyMap propertyMap = new BeanPropertyMap(props, _caseInsensitivePropertyComparison);
propertyMap.assignIndexes();
boolean anyViews = !_defaultViewInclusion;
if (!anyViews) {
for (SettableBeanProperty prop : props) {
if (prop.hasViews()) {
anyViews = true;
break;
}
}
}
if (_objectIdReader != null) {
/* 18-Nov-2012, tatu: May or may not have annotations for id property;
* but no easy access. But hard to see id property being optional,
* so let's consider required at this point.
*/
ObjectIdValueProperty prop = new ObjectIdValueProperty(_objectIdReader,
PropertyMetadata.STD_REQUIRED);
propertyMap = propertyMap.withProperty(prop);
}
return new BuilderBasedDeserializer(this,
_beanDesc, propertyMap, _backRefProperties,
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
/**
* Intermediate base class for limited number of scalar types
* that should never include type information. These are "native"
* types that are default mappings for corresponding JSON scalar
* types: {@link java.lang.String}, {@link java.lang.Integer},
* {@link java.lang.Double} and {@link java.lang.Boolean}.
*/
@SuppressWarnings("serial")
public abstract class NonTypedScalarSerializerBase<T>
extends StdScalarSerializer<T>
{
protected NonTypedScalarSerializerBase(Class<T> t) {
super(t);
}
@Override
public final void serializeWithType(T value, JsonGenerator jgen, SerializerProvider provider,
TypeSerializer typeSer) throws IOException
{
// no type info, just regular serialization
serialize(value, jgen, provider);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.util;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
import com.fasterxml.jackson.databind.type.ClassKey;
/**
* Helper class for caching resolved root names.
*/
public class RootNameLookup implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
/**
* For efficient operation, let's try to minimize number of times we
* need to introspect root element name to use.
*/
protected transient LRUMap<ClassKey,PropertyName> _rootNames;
public RootNameLookup() {
_rootNames = new LRUMap<ClassKey,PropertyName>(20, 200);
}
public PropertyName findRootName(JavaType rootType, MapperConfig<?> config) {
return findRootName(rootType.getRawClass(), config);
}
public PropertyName findRootName(Class<?> rootType, MapperConfig<?> config)
{
ClassKey key = new ClassKey(rootType);
PropertyName name = _rootNames.get(key);
if (name != null) {
return name;
}
BeanDescription beanDesc = config.introspectClassAnnotations(rootType);
AnnotationIntrospector intr = config.getAnnotationIntrospector();
AnnotatedClass ac = beanDesc.getClassInfo();
name = intr.findRootName(ac);
// No answer so far? Let's just default to using simple class name
if (name == null || !name.hasSimpleName()) {
// Should we strip out enclosing class tho? For now, nope:
name = new PropertyName(rootType.getSimpleName());
}
_rootNames.put(key, name);
return name;
}
/*
/**********************************************************
/* Serializable overrides
/**********************************************************
*/
/**
* Need to override to reproduce cache object via constructor, instead
* of serialize/deserialize (since we do NOT want to retain cached data)
*/
protected Object readResolve() {
return new RootNameLookup();
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId;
/**
* Exception thrown during deserialization when there are object id that can't
* be resolved.
*
* @author pgelinas
*/
public final class UnresolvedForwardReference extends JsonMappingException {
private static final long serialVersionUID = 1L;
private ReadableObjectId _roid;
private List<UnresolvedId> _unresolvedIds;
public UnresolvedForwardReference(String msg, JsonLocation loc, ReadableObjectId roid)
{
super(msg, loc);
_roid = roid;
}
public UnresolvedForwardReference(String msg)
{
super(msg);
_unresolvedIds = new ArrayList<UnresolvedId>();
}
// ******************************
// ****** Accessor methods ******
// ******************************
public ReadableObjectId getRoid() {
return _roid;
}
public Object getUnresolvedId() {
return _roid.getKey().key;
}
public void addUnresolvedId(Object id, Class<?> type, JsonLocation where) {
_unresolvedIds.add(new UnresolvedId(id, type, where));
}
public List<UnresolvedId> getUnresolvedIds(){
return _unresolvedIds;
}
@Override
public String getMessage()
{
String msg = super.getMessage();
if (_unresolvedIds == null) {
return msg;
}
StringBuilder sb = new StringBuilder(msg);
Iterator<UnresolvedId> iterator = _unresolvedIds.iterator();
while (iterator.hasNext()) {
UnresolvedId unresolvedId = iterator.next();
sb.append(unresolvedId.toString());
if (iterator.hasNext()) {
sb.append(", ");
}
}
sb.append('.');
return sb.toString();
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.impl;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
/**
* Simple serializer that will call configured type serializer, passing
* in configured data serializer, and exposing it all as a simple
* serializer.
*/
public final class TypeWrappedSerializer
extends JsonSerializer<Object>
{
final protected TypeSerializer _typeSerializer;
final protected JsonSerializer<Object> _serializer;
@SuppressWarnings("unchecked")
public TypeWrappedSerializer(TypeSerializer typeSer, JsonSerializer<?> ser)
{
super();
_typeSerializer = typeSer;
_serializer = (JsonSerializer<Object>) ser;
}
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
_serializer.serializeWithType(value, jgen, provider, _typeSerializer);
}
@Override
public void serializeWithType(Object value, JsonGenerator jgen, SerializerProvider provider,
TypeSerializer typeSer) throws IOException
{
/* Is this an erroneous call? For now, let's assume it is not, and
* that type serializer is just overridden if so
*/
_serializer.serializeWithType(value, jgen, provider, typeSer);
}
@Override
public Class<Object> handledType() { return Object.class; }
/*
/**********************************************************
/* Extended API for other core classes
/**********************************************************
*/
public JsonSerializer<Object> valueSerializer() {
return _serializer;
}
public TypeSerializer typeSerializer() {
return _typeSerializer;
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.jsontype;
import java.util.Collection;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.SerializationConfig;
/**
* Interface that defines builders that are configured based on
* annotations (like {@link com.fasterxml.jackson.annotation.JsonTypeInfo} or JAXB annotations),
* and produce type serializers and deserializers used for
* handling type information embedded in JSON to allow for safe
* polymorphic type handling.
*<p>
* Builder is first initialized by calling {@link #init} method, and then
* configured using 'set' methods like {@link #inclusion}.
* Finally, after calling all configuration methods,
* {@link #buildTypeSerializer} or {@link #buildTypeDeserializer}
* will be called to get actual type resolver constructed
* and used for resolving types for configured base type and its
* subtypes.
*<p>
* Note that instances are used for two related but distinct use cases:
*<ul>
* <li>To create builders to use with explicit type information
* inclusion (usually via <code>@JsonTypeInfo</code> annotation)
* </li>
* <li>To create builders when "default typing" is used; if so, type information
* is automatically included for certain kind of types, regardless of annotations
* </li>
*</ul>
* Important distinction between the cases is that in first case, calls to
* create builders are only made when builders are certainly needed; whereas
* in second case builder has to first verify whether type information is
* applicable for given type, and if not, just return null to indicate this.
*/
public interface TypeResolverBuilder<T extends TypeResolverBuilder<T>>
{
/*
/**********************************************************
/* Accessors
/**********************************************************
*/
/**
* Accessor for currently configured default type; implementation
* class that may be used in case no valid type information is
* available during type resolution
*/
public Class<?> getDefaultImpl();
/*
/**********************************************************
/* Actual builder methods
/**********************************************************
*/
/**
* Method for building type serializer based on current configuration
* of this builder.
*
* @param baseType Base type that constructed resolver will
* handle; super type of all types it will be used for.
*/
public TypeSerializer buildTypeSerializer(SerializationConfig config,
JavaType baseType, Collection<NamedType> subtypes);
/**
* Method for building type
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> deserializer based on current configuration
* of this builder.
*
* @param baseType Base type that constructed resolver will
* handle; super type of all types it will be used for.
* @param subtypes Known subtypes of the base type.
*/
public TypeDeserializer buildTypeDeserializer(DeserializationConfig config,
JavaType baseType, Collection<NamedType> subtypes);
/*
/**********************************************************
/* Initialization method(s) that must be called before other
/* configuration
/**********************************************************
*/
/**
* Initialization method that is called right after constructing
* the builder instance.
*
* @param idType Which type metadata is used
* @param res (optional) Custom type id resolver used, if any
*
* @return Resulting builder instance (usually this builder,
* but not necessarily)
*/
public T init(JsonTypeInfo.Id idType, TypeIdResolver res);
/*
/**********************************************************
/* Methods for configuring resolver to build
/**********************************************************
*/
/**
* Method for specifying mechanism to use for including type metadata
* in JSON.
* If not explicitly called, setting defaults to
* {@link As#PROPERTY}.
*
* @param includeAs Mechanism used for including type metadata in JSON
*
* @return Resulting builder instance (usually this builder,
* but may be a newly constructed instance for immutable builders}
*/
public T inclusion(As includeAs);
/**
* Method for specifying name of property used for including type
* information. Not used for all inclusion mechanisms;
* usually only used with {@link As#PROPERTY}.
*<p>
* If not explicitly called, name of property to use is based on
* defaults for {@link com.fasterxml.jackson.annotation.JsonTypeInfo.Id} configured.
*
* @param propName Name of JSON property to use for including
* type information
*
* @return Resulting builder instance (usually this builder,
* but may be a newly constructed instance for immutable builders}
*/
public T typeProperty(String propName);
/**
* Method for specifying default implementation to use if type id
* is either not available, or can not be resolved.
*
* @return Resulting builder instance (usually this builder,
* but may be a newly constructed instance for immutable builders}
*/
public T defaultImpl(Class<?> defaultImpl);
/**
* Method for specifying whether type id should be visible to
* {@link com.fasterxml.jackson.databind.JsonDeserializer}s or not.
*
* @return Resulting builder instance (usually this builder,
* but may be a newly constructed instance for immutable builders}
*
* @since 2.0
*/
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.jsontype;
import java.util.Collection;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
/**
* Helper object used for handling registration on resolving of super-types
* to sub-types.
*/
public abstract class SubtypeResolver
{
/**
* Method for registering specified subtypes (possibly including type
* names); for type entries without name, non-qualified class name
* as used as name (unless overridden by annotation).
*/
public abstract void registerSubtypes(NamedType... types);
public abstract void registerSubtypes(Class<?>... classes);
/**
* Method for finding out all reachable subtypes for a property specified
* by given element (method or field)
*
* @param baseType Effective property base type to use; may differ from
* actual type of property; for structured types it is content (value) type and NOT
* structured type.
*
* @since 2.1
*/
public abstract Collection<NamedType> collectAndResolveSubtypes(AnnotatedMember property,
MapperConfig<?> config, AnnotationIntrospector ai, JavaType baseType);
/**
* Method for finding out all reachable subtypes for given type.
*/
public abstract Collection<NamedType> collectAndResolveSubtypes(AnnotatedClass basetype,
MapperConfig<?> config, AnnotationIntrospector ai);
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.introspect;
import java.lang.reflect.*;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeBindings;
import com.fasterxml.jackson.databind.util.ClassUtil;
public final class AnnotatedConstructor
extends AnnotatedWithParams
{
private static final long serialVersionUID = 1L;
protected final Constructor<?> _constructor;
/**
* Field that is used to make JDK serialization work with this
* object.
*
* @since 2.1
*/
protected Serialization _serialization;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public AnnotatedConstructor(AnnotatedClass ctxt, Constructor<?> constructor,
AnnotationMap classAnn, AnnotationMap[] paramAnn)
{
super(ctxt, classAnn, paramAnn);
if (constructor == null) {
throw new IllegalArgumentException("Null constructor not allowed");
}
_constructor = constructor;
}
/**
* Method used for JDK serialization support
* @since 2.1
*/
protected AnnotatedConstructor(Serialization ser)
{
super(null, null, null);
_constructor = null;
_serialization = ser;
}
@Override
public AnnotatedConstructor withAnnotations(AnnotationMap ann) {
return new AnnotatedConstructor(_context, _constructor, ann, _paramAnnotations);
}
/*
/**********************************************************
/* Annotated impl
/**********************************************************
*/
@Override
public Constructor<?> getAnnotated() { return _constructor; }
@Override
public int getModifiers() { return _constructor.getModifiers(); }
@Override
public String getName() { return _constructor.getName(); }
@Override
public Type getGenericType() {
return getRawType();
}
@Override
public Class<?> getRawType() {
return _constructor.getDeclaringClass();
}
// note: copied verbatim from AnnotatedMethod; hard to generalize
/**
* As per [JACKSON-468], we need to also allow declaration of local
* type bindings; mostly it will allow defining bounds.
*/
@Override
public JavaType getType(TypeBindings bindings)
{
return getType(bindings, _constructor.getTypeParameters());
}
/*
/**********************************************************
/* Extended API
/**********************************************************
*/
@Override
public int getParameterCount() {
return _constructor.getParameterTypes().length;
}
@Override
public Class<?> getRawParameterType(int index)
{
Class<?>[] types = _constructor.getParameterTypes();
return (index >= types.length) ? null : types[index];
}
@Override
public Type getGenericParameterType(int index)
{
Type
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>[] types = _constructor.getGenericParameterTypes();
return (index >= types.length) ? null : types[index];
}
@Override
public final Object call() throws Exception {
return _constructor.newInstance();
}
@Override
public final Object call(Object[] args) throws Exception {
return _constructor.newInstance(args);
}
@Override
public final Object call1(Object arg) throws Exception {
return _constructor.newInstance(arg);
}
/*
/**********************************************************
/* AnnotatedMember impl
/**********************************************************
*/
@Override
public Class<?> getDeclaringClass() { return _constructor.getDeclaringClass(); }
@Override
public Member getMember() { return _constructor; }
@Override
public void setValue(Object pojo, Object value)
throws UnsupportedOperationException
{
throw new UnsupportedOperationException("Cannot call setValue() on constructor of "
+getDeclaringClass().getName());
}
@Override
public Object getValue(Object pojo)
throws UnsupportedOperationException
{
throw new UnsupportedOperationException("Cannot call getValue() on constructor of "
+getDeclaringClass().getName());
}
/*
/**********************************************************
/* Extended API, specific annotations
/**********************************************************
*/
@Override
public String toString() {
return "[constructor for "+getName()+", annotations: "+_annotations+"]";
}
@Override
public int hashCode() {
return _constructor.getName().hashCode();
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (o == null || o.getClass() != getClass()) return false;
return ((AnnotatedConstructor) o)._constructor == _constructor;
}
/*
/**********************************************************
/* JDK serialization handling
/**********************************************************
*/
Object writeReplace() {
return new AnnotatedConstructor(new Serialization(_constructor));
}
Object readResolve() {
Class<?> clazz = _serialization.clazz;
try {
Constructor<?> ctor = clazz.getDeclaredConstructor(_serialization.args);
// 06-Oct-2012, tatu: Has "lost" its security override, must force back
if (!ctor.isAccessible()) {
ClassUtil.checkAndFixAccess(ctor);
}
return new AnnotatedConstructor(null, ctor, null, null);
} catch (Exception e) {
throw new IllegalArgumentException("Could not find constructor with "
+_serialization.args.length+" args from Class '"+clazz.getName());
}
}
/**
* Helper class that is used as the workaround to persist
* Field references. It basically just stores declaring class
* and field name.
*/
private final static class Serialization
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> protected Class<?> clazz;
protected Class<?>[] args;
public Serialization(Constructor<?> ctor) {
clazz = ctor.getDeclaringClass();
args = ctor.getParameterTypes();
}
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
/**
* To support [JACKSON-420] we need bit more indirection; this is used to produce
* artificial failure for primitives that don't accept JSON null as value.
*/
public final class NullProvider
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
private final Object _nullValue;
private final boolean _isPrimitive;
private final Class<?> _rawType;
public NullProvider(JavaType type, Object nullValue)
{
_nullValue = nullValue;
// [JACKSON-420]
_isPrimitive = type.isPrimitive();
_rawType = type.getRawClass();
}
public Object nullValue(DeserializationContext ctxt) throws JsonProcessingException
{
if (_isPrimitive && ctxt.isEnabled(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)) {
throw ctxt.mappingException("Can not map JSON null into type "+_rawType.getName()
+" (set DeserializationConfig.DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES to 'false' to allow)");
}
return _nullValue;
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> det = _dataFormatReaders;
if (det != null) {
det = det.withType(valueType);
}
return _new(this, _config, valueType, rootDeser,
_valueToUpdate, _schema, _injectableValues, det);
}
/**
* Method for constructing a new reader instance that is configured
* to data bind into specified type.
*<p>
* Note that the method does NOT change state of this reader, but
* rather construct and returns a newly configured instance.
*
* @since 2.5
*/
public ObjectReader forType(Class<?> valueType) {
return forType(_config.constructType(valueType));
}
/**
* Method for constructing a new reader instance that is configured
* to data bind into specified type.
*<p>
* Note that the method does NOT change state of this reader, but
* rather construct and returns a newly configured instance.
*
* @since 2.5
*/
public ObjectReader forType(TypeReference<?> valueTypeRef) {
return forType(_config.getTypeFactory().constructType(valueTypeRef.getType()));
}
/**
* @deprecated since 2.5 Use {@link #forType(JavaType)} instead
*/
@Deprecated
public ObjectReader withType(JavaType valueType) {
return forType(valueType);
}
/**
* @deprecated since 2.5 Use {@link #forType(Class)} instead
*/
@Deprecated
public ObjectReader withType(Class<?> valueType) {
return forType(_config.constructType(valueType));
}
/**
* @deprecated since 2.5 Use {@link #forType(Class)} instead
*/
@Deprecated
public ObjectReader withType(java.lang.reflect.Type valueType) {
return forType(_config.getTypeFactory().constructType(valueType));
}
/**
* @deprecated since 2.5 Use {@link #forType(TypeReference)} instead
*/
@Deprecated
public ObjectReader withType(TypeReference<?> valueTypeRef) {
return forType(_config.getTypeFactory().constructType(valueTypeRef.getType()));
}
/**
* Method for constructing a new instance with configuration that
* updates passed Object (as root value), instead of constructing
* a new value.
*<p>
* Note that the method does NOT change state of this reader, but
* rather construct and returns a newly configured instance.
*/
public ObjectReader withValueToUpdate(Object value)
{
if (value == _valueToUpdate) return this;
if (value == null) {
throw new IllegalArgumentException("cat not update null value");
}
JavaType t;
/* no real
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> benefit from pre-fetching, as updating readers are much
* less likely to be reused, and value type may also be forced
* with a later chained call...
*/
if (_valueType == null) {
t = _config.constructType(value.getClass());
} else {
t = _valueType;
}
return _new(this, _config, t, _rootDeserializer, value,
_schema, _injectableValues, _dataFormatReaders);
}
/**
* Method for constructing a new instance with configuration that
* uses specified View for filtering.
*<p>
* Note that the method does NOT change state of this reader, but
* rather construct and returns a newly configured instance.
*/
public ObjectReader withView(Class<?> activeView) {
return _with(_config.withView(activeView));
}
public ObjectReader with(Locale l) {
return _with(_config.with(l));
}
public ObjectReader with(TimeZone tz) {
return _with(_config.with(tz));
}
public ObjectReader withHandler(DeserializationProblemHandler h) {
return _with(_config.withHandler(h));
}
public ObjectReader with(Base64Variant defaultBase64) {
return _with(_config.with(defaultBase64));
}
/**
* Fluent factory method for constructing a reader that will try to
* auto-detect underlying data format, using specified list of
* {@link JsonFactory} instances, and default {@link DataFormatReaders} settings
* (for customized {@link DataFormatReaders}, you can construct instance yourself).
* to construct appropriate {@link JsonParser} for actual parsing.
*<p>
* Note: since format detection only works with byte sources, it is possible to
* get a failure from some 'readValue()' methods. Also, if input can not be reliably
* (enough) detected as one of specified types, an exception will be thrown.
*<p>
* Note: not all {@link JsonFactory} types can be passed: specifically, ones that
* require "custom codec" (like XML factory) will not work. Instead, use
* method that takes {@link ObjectReader} instances instead of factories.
*
* @param readers Data formats accepted, in decreasing order of priority (that is,
* matches checked in listed order, first match wins)
*
* @return Newly configured writer instance
*
* @since 2.1
*/
public ObjectReader withFormatDetection(ObjectReader... readers) {
return withFormatDetection(new DataFormatReaders(readers));
}
/**
* Fluent factory method for constructing a reader that will try to
* auto-detect underlying data
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> getJsonFactory() {
return _parserFactory;
}
public TypeFactory getTypeFactory() {
return _config.getTypeFactory();
}
/**
* @since 2.3
*/
public ContextAttributes getAttributes() {
return _config.getAttributes();
}
/*
/**********************************************************
/* Deserialization methods; basic ones to support ObjectCodec first
/* (ones that take JsonParser)
/**********************************************************
*/
/**
* Method that binds content read using given parser, using
* configuration of this reader, including expected result type.
* Value return is either newly constructed, or root value that
* was specified with {@link #withValueToUpdate(Object)}.
*<p>
* NOTE: this method never tries to auto-detect format, since actual
* (data-format specific) parser is given.
*/
@SuppressWarnings("unchecked")
public <T> T readValue(JsonParser jp)
throws IOException, JsonProcessingException
{
return (T) _bind(jp, _valueToUpdate);
}
/**
* Convenience method that binds content read using given parser, using
* configuration of this reader, except that expected value type
* is specified with the call (instead of currently configured root type).
* Value return is either newly constructed, or root value that
* was specified with {@link #withValueToUpdate(Object)}.
*<p>
* NOTE: this method never tries to auto-detect format, since actual
* (data-format specific) parser is given.
*/
@SuppressWarnings("unchecked")
@Override
public <T> T readValue(JsonParser jp, Class<T> valueType)
throws IOException, JsonProcessingException
{
return (T) withType(valueType).readValue(jp);
}
/**
* Convenience method that binds content read using given parser, using
* configuration of this reader, except that expected value type
* is specified with the call (instead of currently configured root type).
* Value return is either newly constructed, or root value that
* was specified with {@link #withValueToUpdate(Object)}.
*<p>
* NOTE: this method never tries to auto-detect format, since actual
* (data-format specific) parser is given.
*/
@SuppressWarnings("unchecked")
@Override
public <T> T readValue(JsonParser jp, TypeReference<?> valueTypeRef)
throws IOException, JsonProcessingException
{
return (T) withType(valueTypeRef).readValue(jp);
}
/**
* Convenience method that binds content read using given parser, using
* configuration of this reader, except that expected value type
* is specified with the call (instead of currently configured root type).
* Value return is either newly constructed, or root value
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> that
* was specified with {@link #withValueToUpdate(Object)}.
*<p>
* NOTE: this method never tries to auto-detect format, since actual
* (data-format specific) parser is given.
*/
@Override
@SuppressWarnings("unchecked")
public <T> T readValue(JsonParser jp, ResolvedType valueType) throws IOException, JsonProcessingException {
return (T) withType((JavaType)valueType).readValue(jp);
}
/**
* Type-safe overloaded method, basically alias for {@link #readValue(JsonParser, ResolvedType)}.
*<p>
* NOTE: this method never tries to auto-detect format, since actual
* (data-format specific) parser is given.
*/
@SuppressWarnings("unchecked")
public <T> T readValue(JsonParser jp, JavaType valueType) throws IOException, JsonProcessingException {
return (T) withType(valueType).readValue(jp);
}
/**
* Convenience method that is equivalent to:
*<pre>
* withType(valueType).readValues(jp);
*</pre>
*<p>
* NOTE: this method never tries to auto-detect format, since actual
* (data-format specific) parser is given.
*/
@Override
public <T> Iterator<T> readValues(JsonParser jp, Class<T> valueType)
throws IOException, JsonProcessingException {
return withType(valueType).readValues(jp);
}
/**
* Convenience method that is equivalent to:
*<pre>
* withType(valueTypeRef).readValues(jp);
*</pre>
*<p>
* NOTE: this method never tries to auto-detect format, since actual
* (data-format specific) parser is given.
*/
@Override
public <T> Iterator<T> readValues(JsonParser jp, TypeReference<?> valueTypeRef)
throws IOException, JsonProcessingException {
return withType(valueTypeRef).readValues(jp);
}
/**
* Convenience method that is equivalent to:
*<pre>
* withType(valueType).readValues(jp);
*</pre>
*<p>
* NOTE: this method never tries to auto-detect format, since actual
* (data-format specific) parser is given.
*/
@Override
public <T> Iterator<T> readValues(JsonParser jp, ResolvedType valueType)
throws IOException, JsonProcessingException {
return readValues(jp, (JavaType) valueType);
}
/**
* Convenience method that is equivalent to:
*<pre>
* withType(valueType).readValues(jp);
*</pre>
*<p>
* NOTE
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> public <T> MappingIterator<T> readValues(URL src)
throws IOException, JsonProcessingException
{
if (_dataFormatReaders != null) {
return _detectBindAndReadValues(
_dataFormatReaders.findFormat(_inputStream(src)), true);
}
return _bindAndReadValues(_parserFactory.createParser(src), _valueToUpdate);
}
/*
/**********************************************************
/* Implementation of rest of ObjectCodec methods
/**********************************************************
*/
@Override
public <T> T treeToValue(TreeNode n, Class<T> valueType) throws JsonProcessingException
{
try {
return readValue(treeAsTokens(n), valueType);
} catch (JsonProcessingException e) {
throw e;
} catch (IOException e) { // should not occur, no real i/o...
throw new IllegalArgumentException(e.getMessage(), e);
}
}
@Override
public void writeValue(JsonGenerator jgen, Object value) throws IOException, JsonProcessingException {
throw new UnsupportedOperationException("Not implemented for ObjectReader");
}
/*
/**********************************************************
/* Helper methods, data-binding
/**********************************************************
*/
/**
* Actual implementation of value reading+binding operation.
*/
protected Object _bind(JsonParser jp, Object valueToUpdate) throws IOException
{
/* First: may need to read the next token, to initialize state (either
* before first read from parser, or after previous token has been cleared)
*/
Object result;
JsonToken t = _initForReading(jp);
if (t == JsonToken.VALUE_NULL) {
if (valueToUpdate == null) {
DeserializationContext ctxt = createDeserializationContext(jp, _config);
result = _findRootDeserializer(ctxt, _valueType).getNullValue();
} else {
result = valueToUpdate;
}
} else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) {
result = valueToUpdate;
} else { // pointing to event other than null
DeserializationContext ctxt = createDeserializationContext(jp, _config);
JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, _valueType);
if (_unwrapRoot) {
result = _unwrapAndDeserialize(jp, ctxt, _valueType, deser);
} else {
if (valueToUpdate == null) {
result = deser.deserialize(jp, ctxt);
} else {
deser.deserialize(jp, ctxt, valueToUpdate);
result = valueToUpdate;
}
}
}
// Need to consume the token too
jp.clearCurrentToken();
return result;
}
protected Object _bindAndClose(JsonParser jp, Object valueToUpdate) throws IOException
{
try {
Object
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>>) ser;
_property = null;
_forceTypeInformation = true; // gets reconsidered when we are contextualized
}
@SuppressWarnings("unchecked")
public JsonValueSerializer(JsonValueSerializer src, BeanProperty property,
JsonSerializer<?> ser, boolean forceTypeInfo)
{
super(_notNullClass(src.handledType()));
_accessorMethod = src._accessorMethod;
_valueSerializer = (JsonSerializer<Object>) ser;
_property = property;
_forceTypeInformation = forceTypeInfo;
}
@SuppressWarnings("unchecked")
private final static Class<Object> _notNullClass(Class<?> cls) {
return (cls == null) ? Object.class : (Class<Object>) cls;
}
public JsonValueSerializer withResolved(BeanProperty property,
JsonSerializer<?> ser, boolean forceTypeInfo)
{
if (_property == property && _valueSerializer == ser
&& forceTypeInfo == _forceTypeInformation) {
return this;
}
return new JsonValueSerializer(this, property, ser, forceTypeInfo);
}
/*
/**********************************************************
/* Post-processing
/**********************************************************
*/
/**
* We can try to find the actual serializer for value, if we can
* statically figure out what the result type must be.
*/
@Override
public JsonSerializer<?> createContextual(SerializerProvider provider,
BeanProperty property)
throws JsonMappingException
{
JsonSerializer<?> ser = _valueSerializer;
if (ser == null) {
/* Can only assign serializer statically if the declared type is final:
* if not, we don't really know the actual type until we get the instance.
*/
// 10-Mar-2010, tatu: Except if static typing is to be used
if (provider.isEnabled(MapperFeature.USE_STATIC_TYPING)
|| Modifier.isFinal(_accessorMethod.getReturnType().getModifiers())) {
JavaType t = provider.constructType(_accessorMethod.getGenericReturnType());
// false -> no need to cache
/* 10-Mar-2010, tatu: Ideally we would actually separate out type
* serializer from value serializer; but, alas, there's no access
* to serializer factory at this point...
*/
// 05-Sep-2013, tatu: I _think_ this can be considered a primary property...
ser = provider.findPrimaryPropertySerializer(t, property);
/* 09-Dec-2010, tatu: Turns out we must add special handling for
* cases where "native" (aka "natural") type is being serialized,
* using standard serializer
*/
boolean forceTypeInformation = isNaturalTypeWithStdHandling(t.getRaw
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>Class(), ser);
return withResolved(property, ser, forceTypeInformation);
}
} else {
// 05-Sep-2013, tatu: I _think_ this can be considered a primary property...
ser = provider.handlePrimaryContextualization(ser, property);
return withResolved(property, ser, _forceTypeInformation);
}
return this;
}
/*
/**********************************************************
/* Actual serialization
/**********************************************************
*/
@Override
public void serialize(Object bean, JsonGenerator jgen, SerializerProvider prov) throws IOException
{
try {
Object value = _accessorMethod.invoke(bean);
if (value == null) {
prov.defaultSerializeNull(jgen);
return;
}
JsonSerializer<Object> ser = _valueSerializer;
if (ser == null) {
Class<?> c = value.getClass();
/* 10-Mar-2010, tatu: Ideally we would actually separate out type
* serializer from value serializer; but, alas, there's no access
* to serializer factory at this point...
*/
// let's cache it, may be needed soon again
ser = prov.findTypedValueSerializer(c, true, _property);
}
ser.serialize(value, jgen, prov);
} catch (IOException ioe) {
throw ioe;
} catch (Exception e) {
Throwable t = e;
// Need to unwrap this specific type, to see infinite recursion...
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}
// Errors shouldn't be wrapped (and often can't, as well)
if (t instanceof Error) {
throw (Error) t;
}
// let's try to indicate the path best we can...
throw JsonMappingException.wrapWithPath(t, bean, _accessorMethod.getName() + "()");
}
}
@Override
public void serializeWithType(Object bean, JsonGenerator jgen, SerializerProvider provider,
TypeSerializer typeSer0) throws IOException
{
// Regardless of other parts, first need to find value to serialize:
Object value = null;
try {
value = _accessorMethod.invoke(bean);
// and if we got null, can also just write it directly
if (value == null) {
provider.defaultSerializeNull(jgen);
return;
}
JsonSerializer<Object> ser = _valueSerializer;
if (ser == null) { // already got a serializer? fabulous, that be easy...
// ser = provider.findTypedValueSerializer(value.getClass(), true, _property);
ser = provider.findValueSerializer(
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> null);
}
protected boolean isNaturalTypeWithStdHandling(Class<?> rawType, JsonSerializer<?> ser)
{
// First: do we have a natural type being handled?
if (rawType.isPrimitive()) {
if (rawType != Integer.TYPE && rawType != Boolean.TYPE && rawType != Double.TYPE) {
return false;
}
} else {
if (rawType != String.class &&
rawType != Integer.class && rawType != Boolean.class && rawType != Double.class) {
return false;
}
}
return isDefaultSerializer(ser);
}
/*
/**********************************************************
/* Other methods
/**********************************************************
*/
@Override
public String toString() {
return "(@JsonValue serializer for method " + _accessorMethod.getDeclaringClass() + "#" + _accessorMethod.getName() + ")";
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.deser.std;
import java.io.IOException;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.deser.*;
import com.fasterxml.jackson.databind.introspect.AnnotatedParameter;
import com.fasterxml.jackson.databind.introspect.AnnotatedWithParams;
/**
* Default {@link ValueInstantiator} implementation, which supports
* Creator methods that can be indicated by standard Jackson
* annotations.
*/
@JacksonStdImpl
public class StdValueInstantiator
extends ValueInstantiator
implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
/**
* Type of values that are instantiated; used
* for error reporting purposes.
*/
protected final String _valueTypeDesc;
// // // Default (no-args) construction
/**
* Default (no-argument) constructor to use for instantiation
* (with {@link #createUsingDefault})
*/
protected AnnotatedWithParams _defaultCreator;
// // // With-args (property-based) construction
protected AnnotatedWithParams _withArgsCreator;
protected CreatorProperty[] _constructorArguments;
// // // Delegate construction
protected JavaType _delegateType;
protected AnnotatedWithParams _delegateCreator;
protected CreatorProperty[] _delegateArguments;
// // // Scalar construction
protected AnnotatedWithParams _fromStringCreator;
protected AnnotatedWithParams _fromIntCreator;
protected AnnotatedWithParams _fromLongCreator;
protected AnnotatedWithParams _fromDoubleCreator;
protected AnnotatedWithParams _fromBooleanCreator;
// // // Incomplete creator
protected AnnotatedParameter _incompleteParameter;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
public StdValueInstantiator(DeserializationConfig config, Class<?> valueType) {
_valueTypeDesc = (valueType == null) ? "UNKNOWN TYPE" : valueType.getName();
}
public StdValueInstantiator(DeserializationConfig config, JavaType valueType) {
_valueTypeDesc = (valueType == null) ? "UNKNOWN TYPE" : valueType.toString();
}
/**
* Copy-constructor that sub-classes can use when creating new instances
* by fluent-style construction
*/
protected StdValueInstantiator(StdValueInstantiator src)
{
_valueTypeDesc = src._valueTypeDesc;
_defaultCreator = src._defaultCreator;
_constructorArguments = src._constructorArguments;
_withArgsCreator = src._withArgsCreator;
_delegateType = src._delegateType;
_delegateCreator = src._delegateCreator;
_delegateArguments = src._delegateArguments;
_fromString
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser;
import java.lang.annotation.Annotation;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Base class for writers used to output property values (name-value pairs)
* as key/value pairs via streaming API. This is the most generic abstraction
* implemented by both POJO and {@link java.util.Map} serializers, and invoked
* by filtering functionality.
*
* @since 2.3
*/
public abstract class PropertyWriter
{
/*
/**********************************************************
/* Metadata access
/**********************************************************
*/
public abstract String getName();
public abstract PropertyName getFullName();
/**
* Convenience method for accessing annotation that may be associated
* either directly on property, or, if not, via enclosing class (context).
* This allows adding baseline contextual annotations, for example, by adding
* an annotation for a given class and making that apply to all properties
* unless overridden by per-property annotations.
*<p>
* This method is functionally equivalent to:
*<pre>
* MyAnnotation ann = propWriter.getAnnotation(MyAnnotation.class);
* if (ann == null) {
* ann = propWriter.getContextAnnotation(MyAnnotation.class);
* }
*</pre>
* that is, tries to find a property annotation first, but if one is not
* found, tries to find context-annotation (from enclosing class) of
* same type.
*
* @since 2.5
*/
public <A extends Annotation> A findAnnotation(Class<A> acls) {
A ann = getAnnotation(acls);
if (ann == null) {
ann = getContextAnnotation(acls);
}
return ann;
}
/**
* Method for accessing annotations directly declared for property that this
* writer is associated with.
*
* @since 2.5
*/
public abstract <A extends Annotation> A getAnnotation(Class<A> acls);
/**
* Method for accessing annotations declared in context of the property that this
* writer is associated with; usually this means annotations on enclosing class
* for property.
*
* @since 2.5
*/
public abstract <A extends Annotation> A getContextAnnotation(Class<A> acls);
/*
/**********************************************************
/* Serialization methods, regular output
/**********************************************************
*/
/**
* The main serialization method called by filter when property is to be written normally.
*/
public
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.cfg;
import java.text.DateFormat;
import java.util.Locale;
import java.util.TimeZone;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core.Base64Variant;
import com.fasterxml.jackson.core.SerializableString;
import com.fasterxml.jackson.core.io.SerializedString;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.ClassIntrospector;
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
import com.fasterxml.jackson.databind.jsontype.SubtypeResolver;
import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
import com.fasterxml.jackson.databind.type.TypeBindings;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.databind.util.ClassUtil;
/**
* Interface that defines functionality accessible through both
* serialization and deserialization configuration objects;
* accessors to mode-independent configuration settings
* and such.
* In addition, shared features are defined
* in {@link MapperFeature}.
*<p>
* Small part of implementation is included here by aggregating
* {@link BaseSettings} instance that contains configuration
* that is shared between different types of instances.
*/
public abstract class MapperConfig<T extends MapperConfig<T>>
implements ClassIntrospector.MixInResolver,
java.io.Serializable
{
private static final long serialVersionUID = 1L; // since 2.5
/**
* Set of shared mapper features enabled.
*/
protected final int _mapperFeatures;
/**
* Immutable container object for simple configuration settings.
*/
protected final BaseSettings _base;
/*
/**********************************************************
/* Life-cycle: constructors
/**********************************************************
*/
protected MapperConfig(BaseSettings base, int mapperFeatures)
{
_base = base;
_mapperFeatures = mapperFeatures;
}
protected MapperConfig(MapperConfig<T> src)
{
_base = src._base;
_mapperFeatures = src._mapperFeatures;
}
/**
* Method that calculates bit set (flags) of all features that
* are enabled by default.
*/
public static <F extends Enum<F> & ConfigFeature> int collectFeatureDefaults(Class<F> enumClass)
{
int flags = 0;
for (F value : enumClass.getEnumConstants())
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> return _base.getTypeFactory();
}
/**
* Helper method that will construct {@link JavaType} for given
* raw class.
* This is a simple short-cut for:
*<pre>
* getTypeFactory().constructType(cls);
*</pre>
*/
public final JavaType constructType(Class<?> cls) {
return getTypeFactory().constructType(cls, (TypeBindings) null);
}
/**
* Helper method that will construct {@link JavaType} for given
* type reference
* This is a simple short-cut for:
*<pre>
* getTypeFactory().constructType(valueTypeRef);
*</pre>
*/
public final JavaType constructType(TypeReference<?> valueTypeRef) {
return getTypeFactory().constructType(valueTypeRef.getType(), (TypeBindings) null);
}
public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) {
return getTypeFactory().constructSpecializedType(baseType, subclass);
}
/*
/**********************************************************
/* Configuration: introspection support
/**********************************************************
*/
/**
* Accessor for getting bean description that only contains class
* annotations: useful if no getter/setter/creator information is needed.
*/
public BeanDescription introspectClassAnnotations(Class<?> cls) {
return introspectClassAnnotations(constructType(cls));
}
/**
* Accessor for getting bean description that only contains class
* annotations: useful if no getter/setter/creator information is needed.
*/
public abstract BeanDescription introspectClassAnnotations(JavaType type);
/**
* Accessor for getting bean description that only contains immediate class
* annotations: ones from the class, and its direct mix-in, if any, but
* not from super types.
*/
public BeanDescription introspectDirectClassAnnotations(Class<?> cls) {
return introspectDirectClassAnnotations(constructType(cls));
}
/**
* Accessor for getting bean description that only contains immediate class
* annotations: ones from the class, and its direct mix-in, if any, but
* not from super types.
*/
public abstract BeanDescription introspectDirectClassAnnotations(JavaType type);
/*
/**********************************************************
/* Configuration: other
/**********************************************************
*/
/**
* Method for accessing currently configured (textual) date format
* that will be used for reading or writing date values (in case
* of writing, only if textual output is configured; not if dates
* are to be serialized as time stamps).
*<p>
* Note that typically {@link DateFormat} instances are <b>not thread-safe</b>
* (at least ones provided by JDK):
* this means that calling code should clone format instance
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> before
* using it.
*<p>
* This method is usually only called by framework itself, since there
* are convenience methods available via
* {@link DeserializationContext} and {@link SerializerProvider} that
* take care of cloning and thread-safe reuse.
*/
public final DateFormat getDateFormat() { return _base.getDateFormat(); }
/**
* Method for accessing the default {@link java.util.Locale} to use
* for formatting, unless overridden by local annotations.
* Initially set to {@link Locale#getDefault()}.
*/
public final Locale getLocale() { return _base.getLocale(); }
/**
* Method for accessing the default {@link java.util.TimeZone} to use
* for formatting, unless overridden by local annotations.
* Initially set to {@link TimeZone#getDefault()}.
*/
public final TimeZone getTimeZone() { return _base.getTimeZone(); }
/**
* Accessor for finding currently active view, if any (null if none)
*/
public abstract Class<?> getActiveView();
/**
* Method called during deserialization if Base64 encoded content
* needs to be decoded. Default version just returns default Jackson
* uses, which is modified-mime which does not add linefeeds (because
* those would have to be escaped in JSON strings); but this can
* be configured on {@link ObjectWriter}.
*/
public Base64Variant getBase64Variant() {
return _base.getBase64Variant();
}
/**
* Method for accessing per-instance shared (baseline/default)
* attribute values; these are used as the basis for per-call
* attributes.
*
* @since 2.3
*/
public abstract ContextAttributes getAttributes();
/*
/**********************************************************
/* Methods for instantiating handlers
/**********************************************************
*/
/**
* Method that can be called to obtain an instance of <code>TypeIdResolver</code> of
* specified type.
*/
public TypeResolverBuilder<?> typeResolverBuilderInstance(Annotated annotated,
Class<? extends TypeResolverBuilder<?>> builderClass)
{
HandlerInstantiator hi = getHandlerInstantiator();
if (hi != null) {
TypeResolverBuilder<?> builder = hi.typeResolverBuilderInstance(this, annotated, builderClass);
if (builder != null) {
return builder;
}
}
return (TypeResolverBuilder<?>) ClassUtil.createInstance(builderClass, canOverrideAccessModifiers());
}
/**
* Method that can be called to obtain an instance of <code>TypeIdResolver</code> of
* specified type.
*/
public TypeIdResolver typeIdResolverInstance(Annotated annotated,
Class<? extends TypeIdResolver> resolverClass)
{
HandlerInstantiator hi = get
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> if given member indicates that it is part
* of a reference (parent/child).
*/
public ReferenceProperty findReferenceType(AnnotatedMember member) { return null; }
/**
* Method called to check whether given property is marked to be "unwrapped"
* when being serialized (and appropriately handled in reverse direction,
* i.e. expect unwrapped representation during deserialization).
* Return value is the name transformation to use, if wrapping/unwrapping
* should be done, or null if not -- note that transformation may simply
* be identity transformation (no changes).
*/
public NameTransformer findUnwrappingNameTransformer(AnnotatedMember member) { return null; }
/**
* Method called to check whether given property is marked to
* be ignored. This is used to determine whether to ignore
* properties, on per-property basis, usually combining
* annotations from multiple accessors (getters, setters, fields,
* constructor parameters).
*/
public boolean hasIgnoreMarker(AnnotatedMember m) { return false; }
/**
* Method called to find out whether given member expectes a value
* to be injected, and if so, what is the identifier of the value
* to use during injection.
* Type if identifier needs to be compatible with provider of
* values (of type {@link InjectableValues}); often a simple String
* id is used.
*
* @param m Member to check
*
* @return Identifier of value to inject, if any; null if no injection
* indicator is found
*/
public Object findInjectableValueId(AnnotatedMember m) { return null; }
/**
* Method that can be called to check whether this member has
* an annotation that suggests whether value for matching property
* is required or not.
*
* @since 2.0
*/
public Boolean hasRequiredMarker(AnnotatedMember m) { return null; }
/**
* Method for checking if annotated property (represented by a field or
* getter/setter method) has definitions for views it is to be included in.
* If null is returned, no view definitions exist and property is always
* included (or always excluded as per default view inclusion configuration);
* otherwise it will only be included for views included in returned
* array. View matches are checked using class inheritance rules (sub-classes
* inherit inclusions of super-classes)
*
* @param a Annotated property (represented by a method, field or ctor parameter)
* @return Array of views (represented by classes) that the property is included in;
* if null, always included (same as returning array containing <code>Object.class</code>)
*/
public Class<?>[] findViews(Annotated a) { return null; }
/**
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>; in latter case it is specific
* override for annotated property.
*
* @return Enumerated value indicating which properties to include
* in serialization
*/
public JsonInclude.Include findSerializationInclusion(Annotated a, JsonInclude.Include defValue) {
return defValue;
}
/**
* Method for checking whether content (entries) of a {@link java.util.Map} property
* are to be included during serialization or not.
*
* @since 2.5
*/
public JsonInclude.Include findSerializationInclusionForContent(Annotated a, JsonInclude.Include defValue) {
return defValue;
}
/**
* Method for accessing annotated type definition that a
* method/field can have, to be used as the type for serialization
* instead of the runtime type.
* Type returned (if any) needs to be widening conversion (super-type).
* Declared return type of the method is also considered acceptable.
*
* @return Class to use instead of runtime type
*/
public Class<?> findSerializationType(Annotated a) {
return null;
}
/**
* Method for finding possible widening type definition that a property
* value can have, to define less specific key type to use for serialization.
* It should be only be used with {@link java.util.Map} types.
*
* @return Class specifying more general type to use instead of
* declared type, if annotation found; null if not
*/
public Class<?> findSerializationKeyType(Annotated am, JavaType baseType) {
return null;
}
/**
* Method for finding possible widening type definition that a property
* value can have, to define less specific key type to use for serialization.
* It should be only used with structured types (arrays, collections, maps).
*
* @return Class specifying more general type to use instead of
* declared type, if annotation found; null if not
*/
public Class<?> findSerializationContentType(Annotated am, JavaType baseType) {
return null;
}
/**
* Method for accessing declared typing mode annotated (if any).
* This is used for type detection, unless more granular settings
* (such as actual exact type; or serializer to use which means
* no type information is needed) take precedence.
*
* @return Typing mode to use, if annotation is found; null otherwise
*/
public JsonSerialize.Typing findSerializationTyping(Annotated a) {
return null;
}
/**
* Method for finding {@link Converter} that annotated entity
* (property or class) has indicated to be used as part of
* serialization. If not null, either has to be actual
* {@link Converter} instance, or class for such converter;
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>code>Map</code> property.
* Type of definition is either instance (of type
* {@link JsonDeserializer}) or Class (of type
* <code>Class<JsonDeserializer></code>); if value of different
* type is returned, a runtime exception may be thrown by caller.
*/
public Object findContentDeserializer(Annotated am) {
return null;
}
/**
* Method for accessing annotated type definition that a
* method can have, to be used as the type for serialization
* instead of the runtime type.
* Type must be a narrowing conversion
* (i.e.subtype of declared type).
* Declared return type of the method is also considered acceptable.
*
* @param baseType Assumed type before considering annotations
*
* @return Class to use for deserialization instead of declared type
*/
public Class<?> findDeserializationType(Annotated am, JavaType baseType) {
return null;
}
/**
* Method for accessing additional narrowing type definition that a
* method can have, to define more specific key type to use.
* It should be only be used with {@link java.util.Map} types.
*
* @param baseKeyType Assumed key type before considering annotations
*
* @return Class specifying more specific type to use instead of
* declared type, if annotation found; null if not
*/
public Class<?> findDeserializationKeyType(Annotated am, JavaType baseKeyType) {
return null;
}
/**
* Method for accessing additional narrowing type definition that a
* method can have, to define more specific content type to use;
* content refers to Map values and Collection/array elements.
* It should be only be used with Map, Collection and array types.
*
* @param baseContentType Assumed content (value) type before considering annotations
*
* @return Class specifying more specific type to use instead of
* declared type, if annotation found; null if not
*/
public Class<?> findDeserializationContentType(Annotated am, JavaType baseContentType) {
return null;
}
/**
* Method for finding {@link Converter} that annotated entity
* (property or class) has indicated to be used as part of
* deserialization.
* If not null, either has to be actual
* {@link Converter} instance, or class for such converter;
* and resulting converter will be used after Jackson has deserializer
* data into intermediate type (Converter input type), and Converter
* needs to convert this into its target type to be set as property value.
*<p>
* This feature is typically used to convert intermediate Jackson types
* (that default deserializers can produce) into custom type instances.
*<p>
* Note also that this feature does not necessarily
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> work well with polymorphic
* type handling, or object identity handling; if such features are needed
* an explicit deserializer is usually better way to handle deserialization.
*
* @param a Annotated property (field, method) or class to check for
* annotations
*
* @since 2.2
*/
public Object findDeserializationConverter(Annotated a) {
return null;
}
/**
* Method for finding {@link Converter} that annotated property
* has indicated needs to be used for values of container type
* (this also means that method should only be called for properties
* of container types, List/Map/array properties).
*<p>
* If not null, either has to be actual
* {@link Converter} instance, or class for such converter;
* and resulting converter will be used after Jackson has deserializer
* data into intermediate type (Converter input type), and Converter
* needs to convert this into its target type to be set as property value.
*<p>
* Other notes are same as those for {@link #findDeserializationConverter}
*
* @param a Annotated property (field, method) to check.
*
* @since 2.2
*/
public Object findDeserializationContentConverter(AnnotatedMember a) {
return null;
}
/*
/**********************************************************
/* Deserialization: class annotations
/**********************************************************
*/
/**
* Method getting {@link ValueInstantiator} to use for given
* type (class): return value can either be an instance of
* instantiator, or class of instantiator to create.
*/
public Object findValueInstantiator(AnnotatedClass ac) {
return null;
}
/**
* Method for finding Builder object to use for constructing
* value instance and binding data (sort of combining value
* instantiators that can construct, and deserializers
* that can bind data).
*<p>
* Note that unlike accessors for some helper Objects, this
* method does not allow returning instances: the reason is
* that builders have state, and a separate instance needs
* to be created for each deserialization call.
*
* @since 2.0
*/
public Class<?> findPOJOBuilder(AnnotatedClass ac) {
return null;
}
/**
* @since 2.0
*/
public JsonPOJOBuilder.Value findPOJOBuilderConfig(AnnotatedClass ac) {
return null;
}
/*
/**********************************************************
/* Deserialization: property annotations
/**********************************************************
*/
/**
* Method for checking whether given property accessors (method,
* field) has an annotation that suggests property name to use
* for deserialization (reading JSON into POJOs).
* Should return
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>angle actual access to
* block access ("hide" annotations) or perhaps change it.
*<p>
* Default implementation is simply:
*<code>
* return annotated.getAnnotation(annoClass);
*</code>
*
* @since 2.5
*/
protected <A extends Annotation> A _findAnnotation(Annotated annotated,
Class<A> annoClass) {
return annotated.getAnnotation(annoClass);
}
/**
* Method that should be used by sub-classes for ALL
* annotation existence access;
* overridable so that sub-classes may, if they choose to, mangle actual access to
* block access ("hide" annotations) or perhaps change value seen.
*<p>
* Default implementation is simply:
*<code>
* return annotated.hasAnnotation(annoClass);
*</code>
*
* @since 2.5
*/
protected boolean _hasAnnotation(Annotated annotated, Class<? extends Annotation> annoClass) {
return annotated.hasAnnotation(annoClass);
}
}
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.introspect;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeBindings;
/**
* Shared base class used for anything on which annotations (included
* within a {@link AnnotationMap}).
*/
public abstract class Annotated
{
protected Annotated() { }
public abstract <A extends Annotation> A getAnnotation(Class<A> acls);
public final <A extends Annotation> boolean hasAnnotation(Class<A> acls) {
return getAnnotation(acls) != null;
}
/**
* Fluent factory method that will construct a new instance that uses specified
* instance annotations instead of currently configured ones.
*/
public abstract Annotated withAnnotations(AnnotationMap fallback);
/**
* Fluent factory method that will construct a new instance that uses
* annotations from specified {@link Annotated} as fallback annotations
*/
public final Annotated withFallBackAnnotationsFrom(Annotated annotated) {
return withAnnotations(AnnotationMap.merge(getAllAnnotations(), annotated.getAllAnnotations()));
}
/**
* Method that can be used to find actual JDK element that this instance
* represents. It is non-null, except for method/constructor parameters
* which do not have a JDK counterpart.
*/
public abstract AnnotatedElement getAnnotated();
protected abstract int getModifiers();
public final boolean isPublic() {
return Modifier.isPublic(getModifiers());
}
public abstract String getName();
/**
* Full generic type of the annotated element; definition
* of what exactly this means depends on sub-class.
*/
public JavaType getType(TypeBindings context) {
return context.resolveType(getGenericType());
}
/**
* Full generic type of the annotated element; definition
* of what exactly this means depends on sub-class.
*/
public abstract Type getGenericType();
/**
* "Raw" type (type-erased class) of the annotated element; definition
* of what exactly this means depends on sub-class.
*/
public abstract Class<?> getRawType();
/**
* Accessor that can be used to iterate over all the annotations
* associated with annotated component.
*
* @since 2.3
*/
public abstract Iterable<Annotation> annotations();
/**
* Internal helper method used to access annotation information;
* not exposed to developers since instances are mutable.
*/
protected abstract AnnotationMap getAllAnnotations();
// Also: ensure we can use #equals, #hashCode
@Override
public abstract boolean equals(Object o);
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS> throws IOException, JsonGenerationException {
_append(JsonToken.VALUE_NUMBER_INT, Long.valueOf(l));
}
@Override
public void writeNumber(double d) throws IOException,JsonGenerationException {
_append(JsonToken.VALUE_NUMBER_FLOAT, Double.valueOf(d));
}
@Override
public void writeNumber(float f) throws IOException, JsonGenerationException {
_append(JsonToken.VALUE_NUMBER_FLOAT, Float.valueOf(f));
}
@Override
public void writeNumber(BigDecimal dec) throws IOException,JsonGenerationException {
if (dec == null) {
writeNull();
} else {
_append(JsonToken.VALUE_NUMBER_FLOAT, dec);
}
}
@Override
public void writeNumber(BigInteger v) throws IOException, JsonGenerationException {
if (v == null) {
writeNull();
} else {
_append(JsonToken.VALUE_NUMBER_INT, v);
}
}
@Override
public void writeNumber(String encodedValue) throws IOException, JsonGenerationException {
/* 03-Dec-2010, tatu: related to [JACKSON-423], should try to keep as numeric
* identity as long as possible
*/
_append(JsonToken.VALUE_NUMBER_FLOAT, encodedValue);
}
@Override
public void writeBoolean(boolean state) throws IOException,JsonGenerationException {
_append(state ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE);
}
@Override
public void writeNull() throws IOException, JsonGenerationException {
_append(JsonToken.VALUE_NULL);
}
/*
/***********************************************************
/* JsonGenerator implementation: write methods for POJOs/trees
/***********************************************************
*/
@Override
public void writeObject(Object value) throws IOException
{
if (value == null) {
writeNull();
return;
}
Class<?> raw = value.getClass();
if (raw == byte[].class) {
_append(JsonToken.VALUE_EMBEDDED_OBJECT, value);
return;
} else if (_objectCodec == null) {
/* 28-May-2014, tatu: Tricky choice here; if no codec, should we
* err out, or just embed? For now, do latter.
*/
// throw new JsonMappingException("No ObjectCodec configured for TokenBuffer, writeObject() called");
_append(JsonToken.VALUE_EMBEDDED_OBJECT, value);
} else {
_objectCodec.writeValue(this, value);
}
}
@Override
public void writeTree(TreeNode node) throws IOException
{
if (node == null
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>package com.fasterxml.jackson.databind.ser.std;
import java.io.IOException;
import java.lang.reflect.Type;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsonschema.SchemaAware;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ser.ContainerSerializer;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap;
/**
* Base class for serializers that will output contents as JSON
* arrays; typically serializers used for {@link java.util.Collection}
* and array types.
*/
@SuppressWarnings("serial")
public abstract class AsArraySerializerBase<T>
extends ContainerSerializer<T>
implements ContextualSerializer
{
protected final boolean _staticTyping;
protected final JavaType _elementType;
/**
* Type serializer used for values, if any.
*/
protected final TypeSerializer _valueTypeSerializer;
/**
* Value serializer to use, if it can be statically determined
*/
protected final JsonSerializer<Object> _elementSerializer;
/**
* Collection-valued property being serialized with this instance
*/
protected final BeanProperty _property;
/**
* If element type can not be statically determined, mapping from
* runtime type to serializer is handled using this object
*/
protected PropertySerializerMap _dynamicSerializers;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
protected AsArraySerializerBase(Class<?> cls, JavaType et, boolean staticTyping,
TypeSerializer vts, BeanProperty property, JsonSerializer<Object> elementSerializer)
{
// typing with generics is messy... have to resort to this:
super(cls, false);
_elementType = et;
// static if explicitly requested, or if element type is final
_staticTyping = staticTyping || (et != null && et.isFinal());
_valueTypeSerializer = vts;
_property = property;
_elementSerializer = elementSerializer;
_dynamicSerializers = PropertySerializerMap.emptyForProperties();
}
@SuppressWarnings("unchecked")
protected AsArraySerializerBase(AsArraySerializerBase<?> src,
BeanProperty property, TypeSerializer vts, JsonSerializer<?> elementSerializer)
{
super(src);
JacksonDatabind, 11
<FILEB>
<CHANGES>
context = new TypeBindings(this, (Class<?>) null);
<CHANGEE>
<CHANGES>
JavaType actualType = context.findType(name, false);
<CHANGEE>
<FILEE>
<FILEB>
return CollectionType.construct(rawType, collectionParams[0]);
}
if (paramCount == 0) { // no generics
return new SimpleType(rawType);
}
return constructSimpleType(rawType, pt);
}
protected JavaType _fromArrayType(GenericArrayType type, TypeBindings context)
{
JavaType compType = _constructType(type.getGenericComponentType(), context);
return ArrayType.construct(compType, null, null);
}
protected JavaType _fromVariable(TypeVariable<?> type, TypeBindings context)
{
final String name = type.getName();
// 19-Mar-2015: Without context, all we can check are bounds.
if (context == null) {
// And to prevent infinite loops, now need this:
<CHANGES>
return _unknownType();
<CHANGEE>
} else {
// Ok: here's where context might come in handy!
/* 19-Mar-2015, tatu: As per [databind#609], may need to allow
* unresolved type variables to handle some cases where bounds
* are enough. Let's hope it does not hide real fail cases.
*/
<CHANGES>
JavaType actualType = context.findType(name);
<CHANGEE>
if (actualType != null) {
return actualType;
}
}
/* 29-Jan-2010, tatu: We used to throw exception here, if type was
* bound: but the problem is that this can occur for generic "base"
* method, overridden by sub-class. If so, we will want to ignore
* current type (for method) since it will be masked.
*/
Type[] bounds = type.getBounds();
// With type variables we must use bound information.
// Theoretically this gets tricky, as there may be multiple
<FILEE>
<SCANS>databind.jsonschema.JsonSchema.getDefaultSchemaNode();
}
o.put("items", schemaNode);
}
return o;
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint)
throws JsonMappingException
{
JsonArrayFormatVisitor arrayVisitor = (visitor == null) ? null : visitor.expectArrayFormat(typeHint);
if (arrayVisitor != null) {
/* 01-Sep-2014, tatu: Earlier was trying to make use of 'typeHint' for some
* reason, causing NPE (as per https://github.com/FasterXML/jackson-module-jsonSchema/issues/34)
* if coupled with `@JsonValue`. But I can't see much benefit of trying to rely
* on TypeHint here so code is simplified like so:
*/
JsonSerializer<?> valueSer = _elementSerializer;
if (valueSer == null) {
valueSer = visitor.getProvider().findValueSerializer(_elementType, _property);
}
arrayVisitor.itemsFormat(valueSer, _elementType);
}
}
protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
Class<?> type, SerializerProvider provider) throws JsonMappingException
{
PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property);
// did we get a new map of serializers? If so, start using it
if (map != result.map) {
_dynamicSerializers = result.map;
}
return result.serializer;
}
protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
JavaType type, SerializerProvider provider) throws JsonMappingException
{
PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property);
if (map != result.map) {
_dynamicSerializers = result.map;
}
return result.serializer;
}
}